def render_wato(mini): if not config.wato_enabled: html.write(_("WATO is disabled.")) return False elif not config.may("wato.use"): html.write( _("You are not allowed to use Check_MK's web configuration GUI.")) return False if mini: html.icon_button("wato.py", _("Main Menu"), "home", target="main") else: iconlink(_("Main Menu"), "wato.py", "home") for mode, title, icon, permission, help in wato.modules: if permission and "." not in permission: permission = "wato." + permission if not permission or config.may(permission) or config.may( "wato.seeall"): url = "wato.py?mode=%s" % mode if mini: html.icon_button(url, title, icon, target="main") else: iconlink(title, url, icon) num_pending = wato.num_pending_changes() if num_pending: footnotelinks([(_("%d changes") % num_pending, "wato.py?mode=changelog")]) html.write('<div class=clear></div>')
def ajax_switch_visibility_control(): state = True if int(html.var("state")) is 1 else False # check permissions if config.user_id and config.may('general.edit_profile'): #User DB auslesen users = userdb.load_users(lock=True) user = users.get(config.user_id) # Custom attributes if config.may('general.edit_user_attributes'): for name, attr in userdb.get_user_attributes(): if attr['user_editable']: if name == "force_authuser": users[config.user_id][name] = state userdb.save_users(users) break auth_user_value = 1 if state is True else 0 #render_visibility_control ??? der Aufruf geht hier leider nicht, findet anscheinend die Funktion nicht, deshalb hier doppelter Code ??? html.write("<table class=visibility_control>\n") url = defaults.url_prefix + ("check_mk/switch_user_visibility.py?state=%d") % (1 - auth_user_value) onclick = "get_url('%s', updateContents, 'snapin_visibility_control'); parent.frames[1].location.reload();" % url html.write("<tr><td class=left>See only your own items</td><td>") html.icon_button("#", _("See only your own items %s") % (auth_user_value and "off" or "on"), "snapin_switch_" + (auth_user_value and "on" or "off"), onclick=onclick) html.write("</td></tr>") html.write("</table>") html.set_browser_reload(1) html.reload_sidebar()
def render_snapin(name, state): snapin = sidebar_snapins.get(name) styles = snapin.get("styles") if styles: html.write("<style>\n%s\n</style>\n" % styles) html.write("<div id=\"snapin_container_%s\" class=snapin>\n" % name) if state == "closed": style = ' style="display:none"' headclass = "closed" minimaxi = "maxi" else: style = "" headclass = "open" minimaxi = "mini" toggle_url = "sidebar_openclose.py?name=%s&state=" % name html.write('<div class="head %s" ' % headclass) # If the user may modify the sidebar then add code for dragging the snapin if config.may("general.configure_sidebar"): html.write("onmouseover=\"document.body.style.cursor='move';\" " "onmouseout=\"document.body.style.cursor='';\" " "onmousedown=\"snapinStartDrag(event)\" onmouseup=\"snapinStopDrag(event)\">") else: html.write(">") # Icon for mini/maximizing, does not need permission html.write('<div class="minisnapin">') iconbutton(minimaxi + "snapin", None, "side", "toggle_sidebar_snapin(this, '%s')" % toggle_url, 'snapin_'+name) html.write('</div>') if config.may("general.configure_sidebar"): # Button for closing (removing) a snapin html.write('<div class="closesnapin">') iconbutton("closesnapin", "sidebar_openclose.py?name=%s&state=off" % name, "side", "removeSnapin", 'snapin_'+name) html.write('</div>') # The heading. A click on the heading mini/maximizes the snapin html.write("<b class=heading onclick=\"toggle_sidebar_snapin(this,'%s')\" " "onmouseover=\"this.style.cursor='pointer'\" " "onmouseout=\"this.style.cursor='auto'\">%s</b>" % (toggle_url, snapin["title"])) # End of header html.write("</div>") # Now comes the content html.write("<div id=\"snapin_%s\" class=content%s>\n" % (name, style)) refresh_url = '' try: url = snapin["render"]() # Fetch the contents from an external URL. Don't render it on our own. if not url is None: refresh_url = url html.write('<script>get_url("%s", updateContents, "snapin_%s")</script>' % (refresh_url, name)) except Exception, e: snapin_exception(e)
def sidebar_foot(): html.write('<div id="side_footer">') if config.may("general.configure_sidebar"): html.icon_button("sidebar_add_snapin.py", _("Add snapin to the sidebar"), "sidebar_addsnapin", target="main") if config.may("general.edit_profile") or config.may( "general.change_password"): html.icon_button( "user_profile.py", _("Edit your personal settings, change your password"), "sidebar_settings", target="main") # html.write('<li><a class=profile target="main" href="user_profile.py" title="%s"></a></li>' % _('Edit user profile')) if config.may("general.logout"): html.icon_button("logout.py", _("Log out"), "sidebar_logout", target="_top") # html.write('<li><a class=logout target="_top" href="logout.py" title="%s"></a></li>' % _('Logout')) html.write('</ul>') html.write("<div class=copyright>%s</div>\n" % _( "© <a target=\"_blank\" href=\"http://mathias-kettner.de\">Mathias Kettner</a>" )) html.write('</div>')
def sidebar_foot(): html.write('<div id="side_footer">') if config.may("general.configure_sidebar"): html.icon_button("sidebar_add_snapin.py", _("Add snapin to the sidebar"), "sidebar_addsnapin", target="main") # editing the profile is not possible on remote sites which are sync targets # of a central WATO system if config.wato_enabled and \ (config.may("general.edit_profile") or config.may("general.change_password")): html.icon_button("user_profile.py", _("Edit your personal settings, change your password"), "sidebar_settings", target="main") if config.may("general.logout") and not config.auth_by_http_header: html.icon_button("logout.py", _("Log out"), "sidebar_logout", target="_top") html.icon_button("return void();", _("You have pending messages."), "sidebar_messages", onclick = 'read_message()', id = 'msg_button', style = 'display:none') html.write('<div id="messages" style="display:none;">') render_messages() html.write('</div>') html.write("<div class=copyright>%s</div>\n" % _("© <a target=\"_blank\" href=\"http://mathias-kettner.de\">Mathias Kettner</a>")) html.write('</div>') if load_user_config()["fold"]: html.final_javascript("foldSidebar();")
def page_side(): if not config.may("general.see_sidebar"): return if config.sidebar_notify_interval is not None: interval = config.sidebar_notify_interval else: interval = 'null' html.html_head(_("Check_MK Sidebar"), javascripts=["sidebar"], stylesheets=["sidebar", "status"]) html.write('<body class="side') if config.screenshotmode: html.write(" screenshotmode") html.write( '" onload="initScrollPos(); setSidebarHeight(); init_messages(%s);" ' 'onunload="storeScrollPos()">\n' % interval) html.write('<div id="check_mk_sidebar">\n') views.load_views() sidebar_head() user_config = load_user_config() refresh_snapins = [] restart_snapins = [] scrolling = '' if config.sidebar_show_scrollbar: scrolling = ' class=scroll' html.write('<div id="side_content"%s>' % scrolling) for name, state in user_config["snapins"]: if not name in sidebar_snapins or not config.may("sidesnap." + name): continue # Performs the initial rendering and might return an optional refresh url, # when the snapin contents are refreshed from an external source refresh_url = render_snapin(name, state) if sidebar_snapins.get(name).get("refresh", False): refresh_snapins.append([name, refresh_url]) elif sidebar_snapins.get(name).get("restart", False): refresh_snapins.append([name, refresh_url]) restart_snapins.append(name) html.write('</div>') sidebar_foot() html.write('</div>') html.write("<script language=\"javascript\">\n") if restart_snapins: html.write("sidebar_restart_time = %s\n" % time.time()) html.write("sidebar_update_interval = %0.2f;\n" % config.sidebar_update_interval) html.write("registerEdgeListeners();\n") html.write("setSidebarHeight();\n") html.write("refresh_snapins = %r;\n" % refresh_snapins) html.write("restart_snapins = %r;\n" % restart_snapins) html.write("sidebar_scheduler();\n") html.write("window.onresize = function() { setSidebarHeight(); };\n") html.write( "if (contentFrameAccessible()) { update_content_location(); };\n") html.write("</script>\n") html.body_end()
def render_wato(mini): if not config.wato_enabled: html.write(_("WATO is disabled.")) return False elif not config.may("wato.use"): html.write(_("You are not allowed to use Check_MK's web configuration GUI.")) return False if mini: html.icon_button("wato.py", _("Main Menu"), "home", target="main") else: iconlink(_("Main Menu"), "wato.py", "home") for mode, title, icon, permission, help in wato.modules: if permission and "." not in permission: permission = "wato." + permission if not permission or config.may(permission) or config.may("wato.seeall"): url = "wato.py?mode=%s" % mode if mini: html.icon_button(url, title, icon, target="main") else: iconlink(title, url, icon) num_pending = wato.num_pending_changes() if num_pending: footnotelinks([(_("%d changes") % num_pending, "wato.py?mode=changelog")]) html.write('<div class=clear></div>')
def page_side(): if not config.may("general.see_sidebar"): return if config.sidebar_notify_interval is not None: interval = config.sidebar_notify_interval else: interval = "null" html.html_head(_("Check_MK Sidebar"), javascripts=["sidebar"], stylesheets=["sidebar", "status"]) html.write('<body class="side') if config.screenshotmode: html.write(" screenshotmode") html.write( '" onload="initScrollPos(); setSidebarHeight(); init_messages(%s);" ' 'onunload="storeScrollPos()">\n' % interval ) html.write('<div id="check_mk_sidebar">\n') # FIXME: Move this to the code where views are needed (snapins?) views.load_views() sidebar_head() user_config = load_user_config() refresh_snapins = [] restart_snapins = [] scrolling = "" if config.sidebar_show_scrollbar: scrolling = " class=scroll" html.write('<div id="side_content"%s>' % scrolling) for name, state in user_config["snapins"]: if not name in sidebar_snapins or not config.may("sidesnap." + name): continue # Performs the initial rendering and might return an optional refresh url, # when the snapin contents are refreshed from an external source refresh_url = render_snapin(name, state) if sidebar_snapins.get(name).get("refresh", False): refresh_snapins.append([name, refresh_url]) elif sidebar_snapins.get(name).get("restart", False): refresh_snapins.append([name, refresh_url]) restart_snapins.append(name) html.write("</div>") sidebar_foot() html.write("</div>") html.write('<script language="javascript">\n') if restart_snapins: html.write("sidebar_restart_time = %s\n" % time.time()) html.write("sidebar_update_interval = %0.2f;\n" % config.sidebar_update_interval) html.write("registerEdgeListeners();\n") html.write("setSidebarHeight();\n") html.write("refresh_snapins = %r;\n" % refresh_snapins) html.write("restart_snapins = %r;\n" % restart_snapins) html.write("sidebar_scheduler();\n") html.write("window.onresize = function() { setSidebarHeight(); };\n") html.write("if (contentFrameAccessible()) { update_content_location(); };\n") html.write("</script>\n") html.body_end()
def render_view(view, rows, datasource, group_painters, painters, display_options, painter_options, show_heading, show_buttons, show_checkboxes, layout, num_columns, show_filters, show_footer, hide_filters, browser_reload): home = ("mobile.py", "Home", "home") page = html.var("page") if not page: if view.get("mustsearch"): page = "filter" else: page = "data" title = views.view_title(view) navbar = [("data", _("Results"), "grid", 'results_button'), ("filter", _("Filter"), "search", False)] if config.may("general.act"): navbar.append(("commands", _("Commands"), "gear", False)) # Should we show a page with context links? context_links = [ e for e in views.collect_context_links(view, hide_filters) if e[0].get("mobile") ] if context_links: navbar.append(("context", _("Context"), "arrow-r", False)) page_id = "view_" + view["name"] if page == "filter": jqm_page_header(_("Filter / Search"), left_button=home, id="filter") show_filter_form(show_filters) jqm_page_navfooter(navbar, 'filter', page_id) elif page == "commands": # Page: Commands if config.may("general.act"): jqm_page_header(_("Commands"), left_button=home, id="commands") show_commands = True if html.has_var("_do_actions"): try: show_commands = do_commands(view, datasource["infos"][0], rows) except MKUserError, e: html.show_error(e.message) html.add_user_error(e.varname, e.message) show_commands = True if show_commands: show_command_form(view, datasource, rows) jqm_page_navfooter(navbar, 'commands', page_id)
def page_add_snapin(): if not config.may("general.configure_sidebar"): raise MKGeneralException( _("You are not allowed to change the sidebar.")) html.header(_("Available snapins"), stylesheets=["pages", "sidebar", "status"]) used_snapins = [name for (name, state) in load_user_config()["snapins"]] addname = html.var("name") if addname in sidebar_snapins and addname not in used_snapins and html.check_transaction( ): user_config = load_user_config() user_config["snapins"].append((addname, "open")) save_user_config(user_config) used_snapins = [ name for (name, state) in load_user_config()["snapins"] ] html.reload_sidebar() names = sidebar_snapins.keys() names.sort() html.write('<div class="add_snapin">\n') for name in names: if name in used_snapins: continue if not config.may("sidesnap." + name): continue # not allowed for this user snapin = sidebar_snapins[name] title = snapin["title"] description = snapin.get("description", "") transid = html.get_transid() url = 'sidebar_add_snapin.py?name=%s&_transid=%s&pos=top' % (name, transid) html.write( '<div class=snapinadder ' 'onmouseover="this.style.cursor=\'pointer\';" ' 'onmousedown="window.location.href=\'%s\'; return false;">' % url) html.write("<div class=snapin_preview>") html.write("<div class=clickshield></div>") render_snapin(name, "open") html.write("</div>") html.write("<div class=description>%s</div>" % (description)) html.write("</div>") html.write("</div>\n") html.footer()
def render_view(view, rows, datasource, group_painters, painters, display_options, painter_options, show_heading, show_buttons, show_checkboxes, layout, num_columns, show_filters, show_footer, hide_filters, browser_reload): home=("mobile.py", "Home", "home") page = html.var("page") if not page: if view.get("mustsearch"): page = "filter" else: page = "data" title = views.view_title(view) navbar = [ ( "data", _("Results"), "grid", 'results_button'), ( "filter", _("Filter"), "search", False )] if config.may("general.act"): navbar.append(( "commands", _("Commands"), "gear", False )) # Should we show a page with context links? context_links = [ e for e in views.collect_context_links(view, hide_filters) if e[0].get("mobile") ] if context_links: navbar.append(( "context", _("Context"), "arrow-r", False)) page_id = "view_" + view["name"] if page == "filter": jqm_page_header(_("Filter / Search"), left_button=home, id="filter") show_filter_form(show_filters) jqm_page_navfooter(navbar, 'filter', page_id) elif page == "commands": # Page: Commands if config.may("general.act"): jqm_page_header(_("Commands"), left_button=home, id="commands") show_commands = True if html.has_var("_do_actions"): try: show_commands = do_commands(view, datasource["infos"][0], rows) except MKUserError, e: html.show_error(e.message) html.add_user_error(e.varname, e.message) show_commands = True if show_commands: show_command_form(view, datasource, rows) jqm_page_navfooter(navbar, 'commands', page_id)
def check_limit(self, rows, limit): count = len(rows) if limit != None and count >= limit + 1: text = _("Your query produced more than %d results. ") % limit if self.var("limit", "soft") == "soft" and config.may("general.ignore_soft_limit"): text += '<a href="%s">%s</a>' % \ (self.makeuri([("limit", "hard")]), _('Repeat query and allow more results.')) elif self.var("limit") == "hard" and config.may("general.ignore_hard_limit"): text += '<a href="%s">%s</a>' % \ (self.makeuri([("limit", "none")]), _('Repeat query without limit.')) self.show_warning(text) del rows[limit:] return False return True
def sidebar_foot(): html.write('<div id="side_footer">') if config.may("general.configure_sidebar"): html.icon_button("sidebar_add_snapin.py", _("Add snapin to the sidebar"), "sidebar_addsnapin", target="main") if config.may("general.edit_profile") or config.may("general.change_password"): html.icon_button("user_profile.py", _("Edit your personal settings, change your password"), "sidebar_settings", target="main") # html.write('<li><a class=profile target="main" href="user_profile.py" title="%s"></a></li>' % _('Edit user profile')) if config.may("general.logout"): html.icon_button("logout.py", _("Log out"), "sidebar_logout", target="_top") # html.write('<li><a class=logout target="_top" href="logout.py" title="%s"></a></li>' % _('Logout')) html.write('</ul>') html.write("<div class=copyright>%s</div>\n" % _("© <a target=\"_blank\" href=\"http://mathias-kettner.de\">Mathias Kettner</a>")) html.write('</div>')
def set_livestatus_auth(): user_id = livestatus_auth_user() if user_id != None: _live.set_auth_user('read', user_id) _live.set_auth_user('action', user_id) # May the user see all objects in BI aggregations or only some? if not config.may("bi.see_all"): _live.set_auth_user('bi', user_id) # May the user see all Event Console events or only some? if not config.may("mkeventd.seeall"): _live.set_auth_user('ec', user_id) # Default auth domain is read. Please set to None to switch off authorization _live.set_auth_domain('read')
def move_snapin(): if not config.may("general.configure_sidebar"): return snapname_to_move = html.var("name") beforename = html.var("before") user_config = load_user_config() # Get current state of snaping being moved (open, closed) snap_to_move = None for name, state in user_config["snapins"]: if name == snapname_to_move: snap_to_move = name, state if not snap_to_move: return # snaping being moved not visible. Cannot be. # Build new config by removing snaping at current position # and add before "beforename" or as last if beforename is not set new_snapins = [] for name, state in user_config["snapins"]: if name == snapname_to_move: continue # remove at this position elif name == beforename: new_snapins.append(snap_to_move) new_snapins.append( (name, state) ) if not beforename: # insert as last new_snapins.append(snap_to_move) user_config["snapins"] = new_snapins save_user_config(user_config)
def move_snapin(): if not config.may("general.configure_sidebar"): return snapname_to_move = html.var("name") beforename = html.var("before") snapin_config = load_user_config() # Get current state of snaping being moved (open, closed) snap_to_move = None for name, state in snapin_config: if name == snapname_to_move: snap_to_move = name, state if not snap_to_move: return # snaping being moved not visible. Cannot be. # Build new config by removing snaping at current position # and add before "beforename" or as last if beforename is not set new_config = [] for name, state in snapin_config: if name == snapname_to_move: continue # remove at this position elif name == beforename: new_config.append(snap_to_move) new_config.append((name, state)) if not beforename: # insert as last new_config.append(snap_to_move) save_user_config(new_config)
def may_edit(self): if self.is_builtin(): return False elif self.is_mine(): return True else: return config.may('general.edit_foreign_%s' % self.type_name())
def find_page(self, name): self.load() mine = None forced = None builtin = None foreign = None for page in self.instances(): if page.name() != name: continue if page.is_mine() and config.may("general.edit_" + self.type_name()): mine = page elif page.is_public() and page.may_see(): if page.is_public_forced(): forced = page elif page.is_builtin(): builtin = page else: foreign = page if mine: return mine elif forced: return forced elif builtin: return builtin elif foreign: return foreign else: return None
def pages(self): self.load() pages = {} # Builtin pages for page in self.instances(): if page.is_public() and page.may_see() and page.is_builtin(): pages[page.name()] = page # Public pages by normal other users for page in self.instances(): if page.is_public() and page.may_see(): pages[page.name()] = page # Public pages by admin users, forcing their versions over others for page in self.instances(): if page.is_public() and page.may_see() and page.is_public_forced(): pages[page.name()] = page # My own pages for page in self.instances(): if page.is_mine() and config.may("general.edit_" + self.type_name()): pages[page.name()] = page return sorted(pages.values(), cmp=lambda a, b: cmp(a.title(), b.title()))
def may_delete(self): if self.is_builtin(): return False elif self.is_mine(): return True else: return config.may("general.delete_foreign_%s" % self.type_name())
def show_command_form(view, datasource, rows): what = datasource["infos"][0] html.javascript(""" $(document).ready(function() { $('.command_group').has('x').trigger('expand'); $('x').children().css('background-color', '#f84'); }); """) html.begin_form("commands", html.req.myfile + ".py#commands") html.hidden_field("_do_actions", "yes") html.hidden_field("actions", "yes") html.hidden_fields() # set all current variables, exception action vars one_shown = False html.write('<div data-role="collapsible-set">\n') for command in views.multisite_commands: if what in command["tables"] and config.may(command["permission"]): html.write('<div class="command_group" data-role="collapsible">\n') html.write("<h3>%s</h3>" % command["title"]) html.write('<p>\n') command["render"]() html.write('</p></div>\n') one_shown = True html.write("</div>") if not one_shown: html.write(_('No commands are possible in this view'))
def popup_list_dashboards(): if not config.may("general.edit_dashboards"): return [] load_dashboards() return [(name, board["title"]) for (name, board) in available_dashboards.items()]
def popup_add_dashlet(dashboard_name, dashlet_type, context, params): if not config.may("general.edit_dashboards"): # Exceptions do not work here. return load_dashboards() if dashboard_name not in available_dashboards: return dashboard = load_dashboard_with_cloning(dashboard_name) dashlet = default_dashlet_definition(dashlet_type) dashlet["context"] = context if dashlet_type == 'view': view_name = params['name'] else: dashlet.update(params) # When a view shal be added to the dashboard, load the view and put it into the dashlet if dashlet_type == 'view': # save the original context and override the context provided by the view context = dashlet['context'] load_view_into_dashlet(dashlet, len(dashboard['dashlets']), view_name, add_context=context) add_dashlet(dashlet, dashboard) # Directly go to the dashboard in edit mode. We send the URL as an answer # to the AJAX request html.write('dashboard.py?name=' + dashboard_name + '&edit=1')
def popup_add_dashlet(dashboard_name, dashlet_type, context, params): if not config.may("general.edit_dashboards"): # Exceptions do not work here. return load_dashboards(lock=True) if dashboard_name not in available_dashboards: return dashboard = load_dashboard_with_cloning(dashboard_name) dashlet = default_dashlet_definition(dashlet_type) dashlet["context"] = context if dashlet_type == "view": view_name = params["name"] else: dashlet.update(params) # When a view shal be added to the dashboard, load the view and put it into the dashlet # FIXME: Mave this to the dashlet plugins if dashlet_type == "view": # save the original context and override the context provided by the view context = dashlet["context"] load_view_into_dashlet(dashlet, len(dashboard["dashlets"]), view_name, add_context=context) elif dashlet_type == "pnpgraph": # The "add to visual" popup does not provide a timerang information, # but this is not an optional value. Set it to 25h initially. dashlet.setdefault("timerange", "1") add_dashlet(dashlet, dashboard) # Directly go to the dashboard in edit mode. We send the URL as an answer # to the AJAX request html.write("OK dashboard.py?name=" + dashboard_name + "&edit=1")
def page_side(): if not config.may("general.see_sidebar"): return html.html_head(_("Check_MK Sidebar"), javascripts=["sidebar"], stylesheets=["sidebar", "status"]) html.write( '<body class="side" onload="initScrollPos(); setSidebarHeight();" onunload="storeScrollPos()">\n' ) html.write('<div id="check_mk_sidebar">\n') views.load_views() sidebar_head() user_config = load_user_config() refresh_snapins = [] restart_snapins = [] html.write('<div id="side_content">') for name, state in user_config: if not name in sidebar_snapins or not config.may("sidesnap." + name): continue refresh_url = render_snapin(name, state) refresh_time = sidebar_snapins.get(name).get("refresh", 0) if refresh_time > 0: refresh_snapins.append([name, refresh_time, refresh_url]) restart = sidebar_snapins.get(name, {}).get('restart', False) if restart: restart_snapins.append(name) html.write('</div>') sidebar_foot() html.write('</div>') html.write("<script language=\"javascript\">\n") if restart_snapins: html.write("sidebar_restart_time = %s\n" % time.time()) html.write("registerEdgeListeners();\n") html.write("setSidebarHeight();\n") html.write("refresh_snapins = %r;\n" % refresh_snapins) html.write("restart_snapins = %r;\n" % restart_snapins) html.write("sidebar_scheduler();\n") html.write("window.onresize = function() { setSidebarHeight(); }\n") # html.write("window.onload = function() { setSidebarHeight(); }\n") html.write("</script>\n") # html.write("</div>\n") html.write("</body>\n</html>")
def action_reschedule(): if not config.may("action.reschedule"): raise MKGeneralException("You are not allowed to reschedule checks.") site = html.var("site") host = html.var("host", "") if not host: raise MKGeneralException("Action reschedule: missing host name") service = html.var_utf8("service", "") wait_svc = html.var_utf8("wait_svc", "") if service: cmd = "SVC" what = "service" spec = "%s;%s" % (host, service.encode("utf-8")) if wait_svc: wait_spec = u'%s;%s' % (host, wait_svc) add_filter = "Filter: service_description = %s\n" % wait_svc else: wait_spec = spec add_filter = "Filter: service_description = %s\n" % service else: cmd = "HOST" what = "host" spec = host wait_spec = spec add_filter = "" try: now = int(time.time()) html.live.command("[%d] SCHEDULE_FORCED_%s_CHECK;%s;%d" % (now, cmd, spec, now), site) html.live.set_only_sites([site]) query = u"GET %ss\n" \ "WaitObject: %s\n" \ "WaitCondition: last_check >= %d\n" \ "WaitTimeout: %d\n" \ "WaitTrigger: check\n" \ "Columns: last_check state plugin_output\n" \ "Filter: host_name = %s\n%s" \ % (what, wait_spec, now, config.reschedule_timeout * 1000, host, add_filter) row = html.live.query_row(query) html.live.set_only_sites() last_check = row[0] if last_check < now: html.write("['TIMEOUT', 'Check not executed within %d seconds']\n" % (config.reschedule_timeout)) else: if service == "Check_MK": # Passive services triggered by Check_MK often are updated # a few ms later. We introduce a small wait time in order # to increase the chance for the passive services already # updated also when we return. time.sleep(0.7); html.write("['OK', %d, %d, %r]\n" % (row[0], row[1], row[2].encode("utf-8"))) except Exception, e: html.live.set_only_sites() raise MKGeneralException(_("Cannot reschedule check: %s") % e)
def popup_list_dashboards(): if not config.may("general.edit_dashboards"): return [] load_dashboards() return [ (name, board["title"]) for (name, board) in available_dashboards.items() ]
def page_dashboard(): name = html.var("name", "main") if name not in dashboards: raise MKGeneralException("No such dashboard: '<b>%s</b>'" % name) if not config.may("dashboard.%s" % name): raise MKAuthException(_("You are not allowed to access this dashboard.")) render_dashboard(name)
def page_add_snapin(): if not config.may("general.configure_sidebar"): raise MKGeneralException(_("You are not allowed to change the sidebar.")) html.header(_("Available snapins"), stylesheets=["pages", "sidebar", "status"]) used_snapins = [name for (name, state) in load_user_config()["snapins"]] addname = html.var("name") if addname in sidebar_snapins and addname not in used_snapins and html.check_transaction(): user_config = load_user_config() user_config["snapins"].append((addname, "open")) save_user_config(user_config) used_snapins = [name for (name, state) in load_user_config()["snapins"]] html.reload_sidebar() names = sidebar_snapins.keys() names.sort() html.write('<div class="add_snapin">\n') for name in names: if name in used_snapins: continue if not config.may("sidesnap." + name): continue # not allowed for this user snapin = sidebar_snapins[name] title = snapin["title"] description = snapin.get("description", "") transid = html.get_transid() url = "sidebar_add_snapin.py?name=%s&_transid=%s&pos=top" % (name, transid) html.write( "<div class=snapinadder " "onmouseover=\"this.style.cursor='pointer';\" " "onmousedown=\"window.location.href='%s'; return false;\">" % url ) html.write("<div class=snapin_preview>") html.write("<div class=clickshield></div>") render_snapin(name, "open") html.write("</div>") html.write("<div class=description>%s</div>" % (description)) html.write("</div>") html.write("</div>\n") html.footer()
def may_see(self): perm_name = "%s.%s" % (self.type_name(), self.name()) if config.permission_exists(perm_name) and not config.may(perm_name): return False # if self.owner() == "" and not config.may(perm_name): # return False return True
def load_user_config(): path = config.user_confdir + "/sidebar.mk" try: user_config = eval(file(path).read()) except: user_config = config.sidebar # Remove entries the user is not allowed for or which have state "off" (from legacy version) return [ entry for entry in user_config if entry[1] != "off" and config.may("sidesnap." + entry[0])]
def ajax_snapin(): snapname = html.var("name") if not config.may("sidesnap." + snapname): return snapin = sidebar_snapins.get(snapname) try: snapin["render"]() except Exception, e: snapin_exception(e)
def ack_button(host = None, int_filename = None): if not config.may("general.act") or (host and not may_see(host)): return if int_filename: label = _("Clear Log") else: label = _("Clear Logs") html.context_button(label, html.makeactionuri([('_ack', '1')]), 'delete')
def page_side(): if not config.may("general.see_sidebar"): return html.html_head(_("Check_MK Sidebar"), javascripts=["sidebar"], stylesheets=["sidebar", "status"]) html.write('<body class="side" onload="initScrollPos(); setSidebarHeight();" onunload="storeScrollPos()">\n') html.write('<div id="check_mk_sidebar">\n') views.load_views() sidebar_head() user_config = load_user_config() refresh_snapins = [] restart_snapins = [] html.write('<div id="side_content">') for name, state in user_config: if not name in sidebar_snapins or not config.may("sidesnap." + name): continue refresh_url = render_snapin(name, state) refresh_time = sidebar_snapins.get(name).get("refresh", 0) if refresh_time > 0: refresh_snapins.append([name, refresh_time, refresh_url]) restart = sidebar_snapins.get(name, {}).get('restart', False) if restart: restart_snapins.append(name) html.write('</div>') sidebar_foot() html.write('</div>') html.write("<script language=\"javascript\">\n") if restart_snapins: html.write("sidebar_restart_time = %s\n" % time.time()) html.write("registerEdgeListeners();\n") html.write("setSidebarHeight();\n") html.write("refresh_snapins = %r;\n" % refresh_snapins) html.write("restart_snapins = %r;\n" % restart_snapins) html.write("sidebar_scheduler();\n") html.write("window.onresize = function() { setSidebarHeight(); }\n") # html.write("window.onload = function() { setSidebarHeight(); }\n") html.write("</script>\n") # html.write("</div>\n") html.write("</body>\n</html>")
def do_log_ack(host, filename): todo = [] if not host and not filename: # all logs on all hosts for this_host, logs in all_logs(): for int_filename in logs: file_display = form_file_to_ext(int_filename) todo.append((this_host, int_filename, file_display)) ack_msg = _("all logfiles on all hosts") elif host and not filename: # all logs on one host for int_filename in host_logs(host): file_display = form_file_to_ext(int_filename) todo.append((host, int_filename, file_display)) ack_msg = _("all logfiles of host <tt>%s</tt>") % html.attrencode(host) elif host and filename: # one log on one host int_filename = form_file_to_int(filename) todo = [(host, int_filename, form_file_to_ext(int_filename))] ack_msg = _("the log file <tt>%s</tt> on host <tt>%s</tt>") % (html.attrencode(filename), html.attrencode(host)) html.header(_("Acknowledge %s") % ack_msg, stylesheets=stylesheets) html.begin_context_buttons() html.context_button(_("All Logfiles"), html.makeuri([("host", ""), ("file", "")])) if host: html.context_button(_("All Logfiles of Host"), html.makeuri([("file", "")])) if host and filename: html.context_button(_("Back to Logfile"), html.makeuri([])) html.end_context_buttons() ack = html.var("_ack") if not html.confirm(_("Do you really want to acknowledge %s by <b>deleting</b> all stored messages?") % ack_msg): html.footer() return if not config.may("general.act"): html.write("<h1 class=error>" + _("Permission denied") + "</h1>\n") html.write("<div class=error>" + _("You are not allowed to acknowledge %s</div>") % ack_msg) html.footer() return # filter invalid values if ack != "1": raise MKUserError("_ack", _("Invalid value for ack parameter.")) for this_host, int_filename, display_name in todo: try: if not may_see(this_host): raise MKAuthException(_("Permission denied.")) os.remove(defaults.logwatch_dir + "/" + this_host + "/" + int_filename) except Exception, e: html.show_error( _("The log file <tt>%s</tt> of host <tt>%s</tt> could not be deleted: %s.") % (html.attrencode(file_display), html.attrencode(this_host), e) )
def page_side(): if not config.may("general.see_sidebar"): return html.html_head(_("Check_MK Sidebar"), javascripts=["sidebar"], stylesheets=["sidebar", "status"]) html.write('<body class="side" onload="initScrollPos(); setSidebarHeight();" onunload="storeScrollPos()">\n') html.write('<div id="check_mk_sidebar">\n') views.load_views() sidebar_head() user_config = load_user_config() refresh_snapins = [] restart_snapins = [] html.write('<div id="side_content">') for name, state in user_config: if not name in sidebar_snapins or not config.may("sidesnap." + name): continue # Performs the initial rendering and might return an optional refresh url, # when the snapin contents are refreshed from an external source refresh_url = render_snapin(name, state) if sidebar_snapins.get(name).get("refresh", False): refresh_snapins.append([name, refresh_url]) elif sidebar_snapins.get(name).get("restart", False): refresh_snapins.append([name, refresh_url]) restart_snapins.append(name) html.write('</div>') sidebar_foot() html.write('</div>') html.write("<script language=\"javascript\">\n") if restart_snapins: html.write("sidebar_restart_time = %s\n" % time.time()) html.write("sidebar_update_interval = %0.2f;\n" % config.sidebar_update_interval) html.write("registerEdgeListeners();\n") html.write("setSidebarHeight();\n") html.write("refresh_snapins = %r;\n" % refresh_snapins) html.write("restart_snapins = %r;\n" % restart_snapins) html.write("sidebar_scheduler();\n") html.write("window.onresize = function() { setSidebarHeight(); }\n") html.write("</script>\n") html.write("</body>\n</html>")
def do_log_ack(host, filename): todo = [] if not host and not filename: # all logs on all hosts for this_host, logs in all_logs(): for int_filename in logs: file_display = form_file_to_ext(int_filename) todo.append((this_host, int_filename, file_display)) ack_msg = _('all logfiles on all hosts') elif host and not filename: # all logs on one host for int_filename in host_logs(host): file_display = form_file_to_ext(int_filename) todo.append((host, int_filename, file_display)) ack_msg = _('all logfiles of host %s') % html.attrencode(host) elif host and filename: # one log on one host int_filename = form_file_to_int(filename) todo = [ (host, int_filename, form_file_to_ext(int_filename)) ] ack_msg = _('the log file %s on host %s') % \ (html.attrencode(filename), html.attrencode(host)) html.header(_("Acknowledge %s") % ack_msg, stylesheets = stylesheets) html.begin_context_buttons() html.context_button(_("All Logfiles"), html.makeuri([('host', ''), ('file', '')])) if host: html.context_button(_("All Logfiles of Host"), html.makeuri([('file', '')])) if host and filename: html.context_button(_("Back to Logfile"), html.makeuri([])) html.end_context_buttons() ack = html.var('_ack') if not html.confirm(_("Do you really want to acknowledge %s by <b>deleting</b> all stored messages?") % ack_msg): html.footer() return if not config.may("general.act"): html.write("<h1 class=error>"+_('Permission denied')+"</h1>\n") html.write("<div class=error>" + _('You are not allowed to acknowledge %s</div>') % ack_msg) html.footer() return # filter invalid values if ack != '1': raise MKUserError('_ack', _('Invalid value for ack parameter.')) for this_host, int_filename, display_name in todo: try: if not may_see(this_host): raise MKAuthException(_('Permission denied.')) os.remove(defaults.logwatch_dir + '/' + this_host + '/' + int_filename) except Exception, e: html.show_error(_('The log file <tt>%s</tt> of host <tt>%s</tt> could not be deleted: %s.') % \ (html.attrencode(file_display), html.attrencode(this_host), e))
def load_user_config(): path = config.user_confdir + "/sidebar.mk" try: user_config = eval(file(path).read()) except: user_config = config.sidebar # Remove entries the user is not allowed for or which have state "off" (from legacy version) return [ entry for entry in user_config if entry[1] != "off" and config.may("sidesnap." + entry[0]) ]
def may_see(host): if config.may("general.see_all"): return True # FIXME: Or maybe make completely transparent and add pseudo local_connection() to Single livestatus clas? if config.is_multisite(): conn = html.live.local_connection() else: conn = html.live # livestatus connection is setup with AuthUser return conn.query_value("GET hosts\nStats: state >= 0\nFilter: name = %s\n" % lqencode(host)) > 0
def ack_button(site=None, host_name=None, int_filename=None): if not config.may("general.act") or (host_name and not may_see(site, host_name)): return if int_filename: label = _("Clear Log") else: label = _("Clear Logs") urivars = [('_ack', '1')] if int_filename: urivars.append(("file", int_filename)) html.context_button(label, html.makeactionuri(urivars), 'delete')
def page_delete_dashlet(): if not config.may("general.edit_dashboards"): raise MKAuthException(_("You are not allowed to edit dashboards.")) board = html.var('name') if not board: raise MKGeneralException(_('The name of the dashboard is missing.')) try: ident = int(html.var('id')) except ValueError: raise MKGeneralException(_('Invalid dashlet id')) load_dashboards() if board not in available_dashboards: raise MKGeneralException(_('The requested dashboard does not exist.')) dashboard = available_dashboards[board] try: dashlet = dashboard['dashlets'][ident] except IndexError: raise MKGeneralException(_('The dashlet does not exist.')) html.header(_('Confirm Dashlet Deletion'), stylesheets=["pages", "views"]) html.begin_context_buttons() back_url = html.var('back', 'dashboard.py?name=%s&edit=1' % board) html.context_button(_('Back'), back_url, 'back') html.end_context_buttons() result = html.confirm(_('Do you really want to delete this dashlet?'), method='GET', add_transid=True) if result == False: html.footer() return # confirm dialog shown elif result == True: # do it! try: dashboard['dashlets'].pop(ident) dashboard['mtime'] = int(time.time()) visuals.save('dashboards', dashboards) html.message(_('The dashlet has been deleted.')) except MKUserError, e: html.write("<div class=error>%s</div>\n" % html.attrencode(e.message)) return
def ajax_snapin(): # Update online state of the user (if enabled) userdb.update_user_access_time(config.user_id) snapname = html.var("name") if snapname: snapnames = [snapname] else: snapnames = html.var('names', '').split(',') html.plug() snapin_code = [] try: for snapname in snapnames: if not config.may("sidesnap." + snapname): continue snapin = sidebar_snapins.get(snapname) # When restart snapins are about to be refreshed, only render # them, when the core has been restarted after their initial # rendering if not snapin.get('refresh') and snapin.get('restart'): since = float(html.var('since', 0)) newest = since for site in html.site_status.values(): prog_start = site.get("program_start", 0) if prog_start > newest: newest = prog_start if newest <= since: # no restart snapin_code.append('') continue try: snapin["render"]() except Exception, e: if config.debug: raise snapin_exception(e) snapin_code.append(html.drain()) html.unplug() html.write('[%s]' % ','.join([ '"%s"' % s.replace('"', '\\"').replace('\n', '') for s in snapin_code ]))
def check_ajax_update(): if not config.may("general.edit_dashboards"): raise MKAuthException(_("You are not allowed to edit dashboards.")) board = html.var('name') if not board: raise MKGeneralException(_('The name of the dashboard is missing.')) ident = int(html.var('id')) load_dashboards() if board not in available_dashboards: raise MKGeneralException(_('The requested dashboard does not exist.')) dashboard = available_dashboards[board] try: dashlet = dashboard['dashlets'][ident] except IndexError: raise MKGeneralException(_('The dashlet does not exist.')) return dashlet, dashboard
def ajax_snapin(): snapname = html.var("name") if snapname: snapnames = [ snapname ] else: snapnames = html.var('names', '').split(',') html.plug() snapin_code = [] try: for snapname in snapnames: if not config.may("sidesnap." + snapname): continue snapin = sidebar_snapins.get(snapname) # When restart snapins are about to be refreshed, only render # them, when core restarted after they have been redendered # before if not snapin.get('refresh') and snapin.get('restart'): since = float(html.var('since', 0)) newest = since for site in html.site_status.values(): prog_start = site.get("program_start", 0) if prog_start > newest: newest = prog_start if newest <= since: # no restart snapin_code.append('') continue try: snapin["render"]() except Exception, e: snapin_exception(e) snapin_code.append(html.drain()) html.unplug() html.write('[%s]' % ','.join([ '"%s"' % s.replace('"', '\\"').replace('\n', '') for s in snapin_code]))
def do_log_ack(host, filename): file = form_file_to_int(filename) file_display = form_file_to_ext(file) html.header(_("Acknowledge logfile %s - %s") % (htmllib.attrencode(host), file_display), stylesheets = stylesheets) html.begin_context_buttons() html.context_button(_("All logfiles of Host"), "logwatch.py?host=%s" % htmllib.urlencode(host)) html.end_context_buttons() ack = html.var('ack') if not html.confirm(_("Do you really want to acknowledge the log file <tt>%s</tt> by <b>deleting</b> all stored messages?") % filename): html.footer() return if not (config.may("general.act") and may_see(host)): html.write("<h1 class=error>"+_('Permission denied')+"</h1>\n") html.write("<div class=error>" + _('You are not allowed to acknowledge the logs of the host %s</div>') % htmllib.attrencode(host)) html.footer() return # filter invalid values if ack != '1': raise MKUserError('ack', _('Invalid value for ack parameter.')) try: os.remove(defaults.logwatch_dir + '/' + host + '/' + file) message = '<b>'+_('%s: %s Acknowledged') % (htmllib.attrencode(host), htmllib.attrencode(file_display)) +'</b><br>' message += '<p>' message += _('The log messages from host "%s" in file "%s" have been acknowledged.') % \ (htmllib.attrencode(host), htmllib.attrencode(file_display)) message += '</p>' html.message(message) except Exception, e: html.show_error(_('The log file "%s" from host "%s" could not be deleted: %s.') % \ (htmllib.attrencode(file_display), htmllib.attrencode(host), e))
def load_user_config(): path = config.user_confdir + "/sidebar.mk" try: user_config = eval(file(path).read()) if type(user_config) == list: user_config = { "snapins" : user_config, "fold": False, } except: user_config = { "snapins": config.sidebar, "fold": False, } # Remove entries the user is not allowed for or which have state "off" (from legacy version) # silently skip configured but not existant snapins user_config["snapins"] = [ entry for entry in user_config["snapins"] if entry[0] in sidebar_snapins and entry[1] != "off" and config.may("sidesnap." + entry[0])] return user_config