def render_job_row(cls, job_id, job_status, odd, job_details_back_url=None): html.open_tr(css="data %s0" % odd) # Actions html.open_td(css="job_actions") if job_status.get("may_stop"): html.icon_button(html.makeactionuri([(ActionHandler.stop_job_var, job_id)]), _("Stop this job"), "disable_test") if job_status.get("may_delete"): html.icon_button(html.makeactionuri([(ActionHandler.delete_job_var, job_id)]), _("Delete this job"), "delete") html.close_td() # Job ID html.open_td(css="job_id") uri = makeuri_contextless( request, [ ("mode", "background_job_details"), ("back_url", job_details_back_url), ("job_id", job_id), ], filename="wato.py", ) html.a(job_id, href=uri) html.close_td() # Title html.td(job_status.get("title", _("Background Job")), css="job_title") # State html.td(job_status["state"], css=cls.get_css_for_jobstate(job_status["state"])) # Started html.td(cmk.utils.render.date_and_time(job_status["started"]), css="job_started") # Owner html.td(job_status.get("user", _("Unknown user")), css="job_owner") # PID html.td(job_status["pid"] or "", css="job_pid") # Druation html.td(cmk.utils.render.timespan(job_status.get("duration", 0)), css="job_runtime") # Progress info loginfo = job_status.get("loginfo") if loginfo: if job_status.get("state") == background_job.JobStatusStates.EXCEPTION: html.td(HTML("<br>".join(loginfo["JobException"])), css="job_last_progress") else: progress_text = "" if loginfo["JobProgressUpdate"]: progress_text += "%s" % loginfo["JobProgressUpdate"][-1] html.td(HTML(progress_text), css="job_last_progress") html.td(HTML("<br>".join(loginfo["JobResult"])), css="job_result") else: html.td("", css="job_last_progress") html.td("", css="job_result")
def _display_page_controls(self, start_time, end_time, previous_log_time, next_log_time): html.open_div(class_="paged_controls") def time_url_args(t): return [ ("options_p_start_1_day", time.strftime("%d", time.localtime(t))), ("options_p_start_1_month", time.strftime("%m", time.localtime(t))), ("options_p_start_1_year", time.strftime("%Y", time.localtime(t))), ("options_p_start_sel", "1"), ] if next_log_time is not None: html.icon_button(html.makeactionuri([ ("options_p_start_sel", "0"), ]), _("Most recent events"), "start") html.icon_button(html.makeactionuri(time_url_args(next_log_time)), "%s: %s" % (_("Newer events"), render.date(next_log_time)), "back") else: html.empty_icon_button() html.empty_icon_button() if previous_log_time is not None: html.icon_button(html.makeactionuri(time_url_args(previous_log_time)), "%s: %s" % (_("Older events"), render.date(previous_log_time)), "forth") else: html.empty_icon_button() html.close_div()
def buttons(self): changelog_button() home_button() if self._log_exists() and config.user.may("wato.clear_auditlog") \ and config.user.may("wato.auditlog") and config.user.may("wato.edit"): html.context_button(_("Download"), html.makeactionuri([("_action", "csv")]), "download") if config.user.may("wato.edit"): html.context_button(_("Clear Log"), html.makeactionuri([("_action", "clear")]), "trash")
def buttons(self): super(ModeEditHost, self).buttons() host_status_button(self._host.name(), "hoststatus") html.context_button( _("Services"), watolib.folder_preserving_link([("mode", "inventory"), ("host", self._host.name())]), "services") if watolib.has_agent_bakery() and config.user.may( 'wato.download_agents'): html.context_button( _("Monitoring Agent"), watolib.folder_preserving_link([("mode", "agent_of_host"), ("host", self._host.name())]), "agents") if config.user.may('wato.rulesets'): html.context_button( _("Parameters"), watolib.folder_preserving_link([("mode", "object_parameters"), ("host", self._host.name())]), "rulesets") if self._is_cluster(): html.context_button( _("Clustered Services"), watolib.folder_preserving_link([ ("mode", "edit_ruleset"), ("varname", "clustered_services") ]), "rulesets") if not watolib.Folder.current().locked_hosts(): if config.user.may("wato.rename_hosts"): html.context_button( self._is_cluster() and _("Rename cluster") or _("Rename host"), watolib.folder_preserving_link([("mode", "rename_host"), ("host", self._host.name()) ]), "rename_host") html.context_button( self._is_cluster() and _("Delete cluster") or _("Delete host"), html.makeactionuri([("delete", "1")]), "delete") if not self._is_cluster(): html.context_button( _("Diagnostic"), watolib.folder_preserving_link([("mode", "diag_host"), ("host", self._host.name())]), "diagnose") html.context_button(_("Update DNS Cache"), html.makeactionuri([("_update_dns_cache", "1")]), "update")
def _page_menu_entry_acknowledge( site: Optional[config.SiteId] = None, host_name: Optional[HostName] = None, int_filename: Optional[str] = None) -> Iterator[PageMenuEntry]: if not config.user.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: HTTPVariables = [('_ack', '1')] if int_filename: urivars.append(("file", form_file_to_ext(int_filename))) ack_msg = _get_ack_msg( host_name, form_file_to_ext(int_filename) if int_filename else None) yield PageMenuEntry( title=label, icon_name="delete", item=make_simple_link( make_confirm_link( url=html.makeactionuri(urivars), message=_("Do you really want to acknowledge %s " "by <b>deleting</b> all stored messages?") % ack_msg, )), is_shortcut=True, is_suggested=True, )
def page(self): with table_element(title=self._table_title(), searchable=False, sortable=False) as table: for key_id, key in sorted(self.keys.items()): cert = crypto.load_certificate(crypto.FILETYPE_PEM, key["certificate"]) table.row() table.cell(_("Actions"), css="buttons") if self._may_edit_config(): delete_url = html.makeactionuri([("_delete", key_id)]) html.icon_button(delete_url, _("Delete this key"), "delete") download_url = html.makeuri_contextless([("mode", self.download_mode), ("key", key_id)]) html.icon_button(download_url, _("Download this key"), "download") table.cell(_("Description"), html.render_text(key["alias"])) table.cell(_("Created"), cmk.utils.render.date(key["date"])) table.cell(_("By"), html.render_text(key["owner"])) table.cell( _("Digest (MD5)"), html.render_text(cert.digest("md5").decode("ascii")))
def page(self): with table_element(title=self._table_title(), searchable=False, sortable=False) as table: for key_id, key in sorted(self.keys.items()): cert = crypto.load_certificate(crypto.FILETYPE_PEM, key["certificate"]) table.row() table.cell(_("Actions"), css="buttons") if self._may_edit_config(): message = self._delete_confirm_msg() if key["owner"] != config.user.id: message += _("<br><b>Note</b>: this key has created by user <b>%s</b>" ) % key["owner"] delete_url = make_confirm_link( url=html.makeactionuri([("_delete", key_id)]), message=message, ) html.icon_button(delete_url, _("Delete this key"), "delete") download_url = makeuri_contextless( request, [("mode", self.download_mode), ("key", key_id)], ) html.icon_button(download_url, _("Download this key"), "download") table.cell(_("Description"), key["alias"]) table.cell(_("Created"), cmk.utils.render.date(key["date"])) table.cell(_("By"), key["owner"]) table.cell(_("Digest (MD5)"), cert.digest("md5").decode("ascii"))
def _show_move_to_folder_action(self, obj): if isinstance(obj, watolib.Host): what = "host" what_title = _("host") ident = obj.name() style = None else: what = "folder" what_title = _("folder") ident = obj.path() style = "display:none" html.popup_trigger( html.render_icon("move", title=_("Move this %s to another folder") % what_title, cssclass="iconbutton"), ident="move_" + obj.name(), what="move_to_folder", url_vars=[ ("what", what), ("ident", ident), ("back_url", html.makeactionuri([])), ], style=style, )
def page(self): if not self._attrs: html.div(_("No custom attributes are defined yet."), class_="info") return with table_element(self._type + "attrs") as table: for custom_attr in sorted(self._attrs, key=lambda x: x['title']): table.row() table.cell(_("Actions"), css="buttons") edit_url = watolib.folder_preserving_link([ ("mode", "edit_%s_attr" % self._type), ("edit", custom_attr['name']) ]) delete_url = make_confirm_link( url=html.makeactionuri([("_delete", custom_attr['name'])]), message= _('Do you really want to delete the custom attribute "%s"?' ) % custom_attr['name'], ) html.icon_button(edit_url, _("Properties"), "edit") html.icon_button(delete_url, _("Delete"), "delete") table.text_cell(_("Name"), custom_attr['name']) table.text_cell(_("Title"), custom_attr['title']) table.cell(_("Type"), dict(custom_attr_types())[custom_attr['type']])
def delete_site(cls, site_id): # TODO: Clean this up from cmk.gui.watolib.hosts_and_folders import Folder all_sites = cls.load_sites() if site_id not in all_sites: raise MKUserError(None, _("Unable to delete unknown site id: %s") % site_id) # Make sure that site is not being used by hosts and folders if site_id in Folder.root_folder().all_site_ids(): search_url = html.makeactionuri([ ("host_search_change_site", "on"), ("host_search_site", site_id), ("host_search", "1"), ("folder", ""), ("mode", "search"), ("filled_in", "edit_host"), ]) raise MKUserError( None, _("You cannot delete this connection. It has folders/hosts " "assigned to it. You can use the <a href=\"%s\">host " "search</a> to get a list of the hosts.") % search_url) domains = cls._affected_config_domains() del all_sites[site_id] cls.save_sites(all_sites) cmk.gui.watolib.activate_changes.clear_site_replication_status(site_id) cmk.gui.watolib.changes.add_change("edit-sites", _("Deleted site %s") % site_id, domains=domains, sites=[default_site()])
def _extend_display_dropdown(self, menu: PageMenu) -> None: display_dropdown = menu.get_dropdown_by_name("display", make_display_options_dropdown()) display_dropdown.topics.insert( 0, PageMenuTopic( title=_("Filter"), entries=[ PageMenuEntry( title=_("Filter view"), icon_name="filters_set" if html.form_submitted("options") else "filter", item=PageMenuSidePopup(self._render_filter_form()), name="filters", is_shortcut=True, ), ], )) display_dropdown.topics.insert( 0, PageMenuTopic( title=_("Details"), entries=[ PageMenuEntry( title=_("Hide details") if self._show_details else _("Show details"), icon_name="checkbox", item=make_simple_link( html.makeactionuri([ ("show_details", "0" if self._show_details else "1"), ])), name="show_details", css_classes=["toggle"], ) ], ))
def page_menu(self, breadcrumb: Breadcrumb) -> PageMenu: return PageMenu( dropdowns=[ PageMenuDropdown( name="hosts", title=_("Hosts"), topics=[ self._page_menu_save_topic(), PageMenuTopic( title=_("For this host"), entries=list(page_menu_host_entries(self.name(), self._host)), ), PageMenuTopic( title=_("For all hosts on site %s") % self._host.site_id(), entries=[ PageMenuEntry( title=_("Update DNS cache"), icon_name="update", item=make_simple_link( html.makeactionuri([("_update_dns_cache", "1")])), shortcut_title=_("Update site DNS cache"), is_shortcut=True, is_suggested=True, ), ], ), ], ), ], breadcrumb=breadcrumb, )
def _page_menu_entries_details(self) -> Iterator[PageMenuEntry]: yield PageMenuEntry( title=_("Show all settings") if self._show_only_modified else _("Show only modified settings"), icon_name="checkbox", item=make_simple_link( html.makeactionuri([ ("_show_only_modified", "0" if self._show_only_modified else "1"), ])), )
def _page_menu_entries_ack_all_werks() -> Iterator[PageMenuEntry]: if not may_acknowledge(): return yield PageMenuEntry( title=_("Acknowledge all"), icon_name="werk_ack", item=make_simple_link(html.makeactionuri([("_ack_all", "1")])), is_enabled=bool(unacknowledged_incompatible_werks()), )
def page_menu_all_hosts_entries(should_use_dns_cache: bool) -> Iterator[PageMenuEntry]: if should_use_dns_cache: yield PageMenuEntry( title=_("Update DNS cache"), icon_name="update", item=make_simple_link(html.makeactionuri([("_update_dns_cache", "1")])), shortcut_title=_("Update site DNS cache"), is_shortcut=True, is_suggested=True, )
def show_annotations(annotations, av_rawdata, what, avoptions, omit_service): annos_to_render = get_relevant_annotations(annotations, av_rawdata, what, avoptions) render_date = get_annotation_date_render_function(annos_to_render, avoptions) with table_element(title=_("Annotations"), omit_if_empty=True) as table: for (site_id, host, service), annotation in annos_to_render: table.row() table.cell("", css="buttons") anno_vars = [ ("anno_site", site_id), ("anno_host", host), ("anno_service", service or ""), ("anno_from", int(annotation["from"])), ("anno_until", int(annotation["until"])), ] edit_url = html.makeuri(anno_vars) html.icon_button(edit_url, _("Edit this annotation"), "edit") del_anno = [("_delete_annotation", "1")] # type: HTTPVariables delete_url = html.makeactionuri(del_anno + anno_vars) html.icon_button(delete_url, _("Delete this annotation"), "delete") if not omit_service: if "omit_host" not in avoptions["labelling"]: host_url = "view.py?" + html.urlencode_vars([("view_name", "hoststatus"), ("site", site_id), ("host", host)]) table.cell(_("Host"), html.render_a(host, host_url)) if what == "service": if service: service_url = "view.py?" + html.urlencode_vars([("view_name", "service"), ("site", site_id), ("host", host), ("service", service)]) # TODO: honor use_display_name. But we have no display names here... service_name = service table.cell(_("Service"), html.render_a(service_name, service_url)) else: table.cell(_("Service"), "") # Host annotation in service table table.cell(_("From"), render_date(annotation["from"]), css="nobr narrow") table.cell(_("Until"), render_date(annotation["until"]), css="nobr narrow") table.cell("", css="buttons") if annotation.get("downtime") is True: html.icon(_("This period has been reclassified as a scheduled downtime"), "downtime") elif annotation.get("downtime") is False: html.icon( _("This period has been reclassified as a not being a scheduled downtime"), "nodowntime") table.cell(_("Annotation"), html.render_text(annotation["text"])) table.cell(_("Author"), annotation["author"]) table.cell(_("Entry"), render_date(annotation["date"]), css="nobr narrow") if not cmk_version.is_raw_edition(): table.cell(_("Hide in report"), _("Yes") if annotation.get("hide_from_report") else _("No"))
def _page_menu_entries_all_sites(self) -> Iterator[PageMenuEntry]: if not self._may_activate_changes(): return yield PageMenuEntry( title=_("Discard all pending changes"), icon_name="delete", item=make_simple_link(html.makeactionuri([("_action", "discard")])), name="discard_changes", is_enabled=self.has_changes() and self._get_last_wato_snapshot_file(), )
def page_werk(): load_werks() werk_id = html.request.get_integer_input_mandatory("werk") if werk_id not in g_werks: raise MKUserError("werk", _("This werk does not exist.")) werk = g_werks[werk_id] html.header( ("%s %s - %s") % (_("Werk"), render_werk_id(werk, with_link=False), werk["title"])) html.begin_context_buttons() back_url = html.makeuri([], filename="version.py", delvars=["werk"]) # keeps filter settings html.context_button(_("Back"), back_url, "back") if werk["compatible"] == "incomp_unack" and may_acknowledge(): ack_url = html.makeactionuri([("_werk_ack", werk["id"])], filename="version.py") html.context_button(_("Acknowledge"), ack_url, "werk_ack") html.end_context_buttons() html.open_table(class_=["data", "headerleft", "werks"]) def werk_table_row(caption, content, css=None): html.open_tr() html.th(caption) html.open_td(class_=css) html.write(content) html.close_td() html.close_tr() translator = cmk.utils.werks.WerkTranslator() werk_table_row(_("ID"), render_werk_id(werk, with_link=False)) werk_table_row(_("Title"), html.render_b(render_werk_title(werk))) werk_table_row(_("Component"), translator.component_of(werk)) werk_table_row(_("Date"), render_werk_date(werk)) werk_table_row(_("Checkmk Version"), werk["version"]) werk_table_row(_("Level"), translator.level_of(werk), css="werklevel werklevel%d" % werk["level"]) werk_table_row(_("Class"), translator.class_of(werk), css="werkclass werkclass%s" % werk["class"]) werk_table_row(_("Compatibility"), translator.compatibility_of(werk), css="werkcomp werkcomp%s" % werk["compatible"]) werk_table_row(_("Description"), render_werk_description(werk), css="nowiki") html.close_table() html.footer()
def _show_row_cells(self, table, name, group): table.cell(_("Actions"), css="buttons") edit_url = watolib.folder_preserving_link([("mode", "edit_%s_group" % self.type_name), ("edit", name)]) delete_url = html.makeactionuri([("_delete", name)]) clone_url = watolib.folder_preserving_link([("mode", "edit_%s_group" % self.type_name), ("clone", name)]) html.icon_button(edit_url, _("Properties"), "edit") html.icon_button(clone_url, _("Create a copy of this group"), "clone") html.icon_button(delete_url, _("Delete"), "delete") table.cell(_("Name"), html.attrencode(name)) table.cell(_("Alias"), html.attrencode(group['alias']))
def _page_menu_entries_ack_werk( werk: Dict[str, Any]) -> Iterator[PageMenuEntry]: if not may_acknowledge(): return ack_url = html.makeactionuri([("_werk_ack", werk["id"])], filename="version.py") yield PageMenuEntry( title=_("Acknowledge"), icon_name="werk_ack", item=make_simple_link(ack_url), is_enabled=werk["compatible"] == "incomp_unack", )
def ack_button(site=None, host_name=None, int_filename=None): if not config.user.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')] # type: HTTPVariables if int_filename: urivars.append(("file", int_filename)) html.context_button(label, html.makeactionuri(urivars), 'delete')
def _page_menu_entries_synchronized_users(self) -> Iterator[PageMenuEntry]: if userdb.sync_possible(): if not self._job_snapshot.is_active(): yield PageMenuEntry( title=_("Synchronize users"), icon_name="replicate", item=make_simple_link(html.makeactionuri([("_sync", 1)])), ) yield PageMenuEntry( title=_("Last synchronization result"), icon_name="background_job_details", item=make_simple_link(self._job.detail_url()), )
def _show_row_cells(self, table, name, group): table.cell(_("Actions"), css="buttons") edit_url = watolib.folder_preserving_link([("mode", "edit_%s_group" % self.type_name), ("edit", name)]) delete_url = make_confirm_link( url=html.makeactionuri([("_delete", name)]), message=_('Do you really want to delete the %s group "%s"?') % (self.type_name, name)) clone_url = watolib.folder_preserving_link([("mode", "edit_%s_group" % self.type_name), ("clone", name)]) html.icon_button(edit_url, _("Properties"), "edit") html.icon_button(clone_url, _("Create a copy of this group"), "clone") html.icon_button(delete_url, _("Delete"), "delete") table.cell(_("Name"), escaping.escape_attribute(name)) table.cell(_("Alias"), escaping.escape_attribute(group['alias']))
def _page_menu_entries_actions(self) -> Iterator[PageMenuEntry]: if not self._log_exists(): return if not config.user.may("wato.auditlog"): return if not config.user.may("wato.edit"): return if config.user.may("wato.clear_auditlog"): yield PageMenuEntry( title=_("Clear log"), icon_name="trash", item=make_simple_link(html.makeactionuri([("_action", "clear")])), )
def render_unacknowleged_werks(): werks = unacknowledged_incompatible_werks() if werks and may_acknowledge(): html.begin_context_buttons() html.context_button(_("Acknowledge all"), html.makeactionuri([("_ack_all", "1")]), "werk_ack") html.end_context_buttons() if werks and not html.request.has_var("show_unack"): html.open_div(class_=["warning"]) html.write_text( _("<b>Warning:</b> There are %d unacknowledged incompatible werks:") % len(werks)) html.br() html.br() html.a(_("Show unacknowledged incompatible werks"), href=html.makeuri_contextless([("show_unack", "1"), ("wo_compatibility", "3")])) html.close_div()
def buttons(self): home_button() # TODO: Remove once new changes mechanism has been implemented if self._may_discard_changes(): html.context_button(_("Discard Changes!"), html.makeactionuri([("_action", "discard")]), "discard", id_="discard_changes_button") if config.user.may("wato.sites"): html.context_button(_("Site Configuration"), watolib.folder_preserving_link([("mode", "sites")]), "sites") if config.user.may("wato.auditlog"): html.context_button(_("Audit Log"), watolib.folder_preserving_link([("mode", "auditlog")]), "auditlog")
def _page_menu_entries_export(self) -> Iterator[PageMenuEntry]: if not self._log_exists(): return if not config.user.may("wato.auditlog"): return if not config.user.may("wato.edit"): return if not config.user.may("general.csv_export"): return yield PageMenuEntry( title=_("Export CSV"), icon_name="download_csv", item=make_simple_link(html.makeactionuri([("_action", "csv")])), )
def _page_menu_entries_ack_all_werks() -> Iterator[PageMenuEntry]: if not may_acknowledge(): return yield PageMenuEntry( title=_("Acknowledge all"), icon_name="werk_ack", is_shortcut=True, is_suggested=True, item=make_simple_link( make_confirm_link( url=html.makeactionuri([("_ack_all", "1")]), message= _("Do you really want to acknowledge <b>all</b> incompatible werks?" ), )), is_enabled=bool(unacknowledged_incompatible_werks()), )
def buttons(self): global_buttons() html.context_button(_("New user"), watolib.folder_preserving_link([("mode", "edit_user")]), "new") if config.user.may("wato.custom_attributes"): html.context_button(_("Custom attributes"), watolib.folder_preserving_link([("mode", "user_attrs")]), "custom_attr") if userdb.sync_possible(): if not self._job_snapshot.is_active(): html.context_button(_("Sync users"), html.makeactionuri([("_sync", 1)]), "replicate") html.context_button(_("Last sync result"), self._job.detail_url(), "background_job_details") if config.user.may("general.notify"): html.context_button(_("Notify users"), 'notify.py', "notification") html.context_button(_("LDAP connections"), watolib.folder_preserving_link([("mode", "ldap_config")]), "ldap")
def render_page_confirm(acktime, failed_notifications): title = _("Confirm failed notifications") breadcrumb = make_simple_page_breadcrumb( mega_menu_registry.menu_monitoring(), title) confirm_url = make_simple_link( make_confirm_link( url=html.makeactionuri([("acktime", str(acktime)), ("_confirm", "1")]), message= _("Do you really want to acknowledge all failed notifications up to %s?" ) % cmk.utils.render.date_and_time(acktime), )) page_menu = PageMenu( dropdowns=[ PageMenuDropdown( name="actions", title=_("Actions"), topics=[ PageMenuTopic( title=_("Actions"), entries=[ PageMenuEntry( title=_("Confirm"), icon_name="save", item=confirm_url, is_shortcut=True, is_suggested=True, is_enabled=failed_notifications, ), ], ), ], ), ], breadcrumb=breadcrumb, ) html.header(title, breadcrumb, page_menu) render_notification_table(failed_notifications) html.footer()