def page(self): # TODO: remove subclass specific things specifict things (everything with _type == 'user') html.begin_form("attr") forms.header(_("Properties")) forms.section(_("Name"), simple=not self._new, is_required=True) html.help( _( "The name of the attribute is used as an internal key. It cannot be " "changed later." ) ) if self._new: html.text_input("name", self._attr.get("name", "")) html.set_focus("name") else: html.write_text(self._name) html.set_focus("title") forms.section(_("Title") + "<sup>*</sup>", is_required=True) html.help(_("The title is used to label this attribute.")) html.text_input("title", self._attr.get("title", "")) forms.section(_("Topic")) html.help(_("The attribute is added to this section in the edit dialog.")) html.dropdown("topic", self._topics, deflt=self._attr.get("topic", self._default_topic)) forms.section(_("Help Text") + "<sup>*</sup>") html.help(_("You might want to add some helpful description for the attribute.")) html.text_area("help", self._attr.get("help", "")) forms.section(_("Data type")) html.help(_("The type of information to be stored in this attribute.")) if self._new: html.dropdown("type", custom_attr_types(), deflt=self._attr.get("type", "")) else: html.write_text(dict(custom_attr_types())[self._attr.get("type")]) self._add_extra_form_sections() self._show_in_table_option() forms.section(_("Add to monitoring configuration")) html.help(self._macro_help) html.checkbox( "add_custom_macro", self._attr.get("add_custom_macro", False), label=self._macro_label ) forms.end() html.show_localization_hint() html.hidden_fields() html.end_form()
def display(self, value: FilterHTTPVariables): html.open_table(class_="filtertime") for what, whatname in [("from", _("From")), ("until", _("Until"))]: varprefix = self.ident + "_" + what html.open_tr() html.td("%s:" % whatname) html.open_td() html.text_input(varprefix, default_value=value.get(varprefix, "")) html.close_td() html.open_td() html.dropdown( varprefix + "_range", query_filters.time_filter_options(), deflt=value.get(varprefix + "_range", "3600"), ) html.close_td() html.close_tr() html.close_table()
def _show_tree_selection(self): html.begin_form("vtree") html.dropdown( "vtree", self._tree_choices(), deflt="%s" % self._current_tree_id, onchange="virtual_host_tree_changed(this)", style="width:210px" if self._current_tree_path else None, ) # Give chance to change one level up, if we are in a subtree if self._current_tree_path: upurl = "javascript:virtual_host_tree_enter('%s')" % "|".join( self._current_tree_path[:-1]) html.icon_button(upurl, _("Go up one tree level"), "back") html.br() html.end_form() html.final_javascript(self._javascript())
def snapin_site_choice( ident: str, choices: List[Tuple[SiteId, str]]) -> Optional[List[SiteId]]: sites = user.load_file("sidebar_sites", {}) available_site_choices = filter_available_site_choices(choices) site = sites.get(ident, "") if site == "": only_sites = None else: only_sites = [site] if len(available_site_choices) <= 1: return None dropdown_choices: Choices = [ ("", _("All sites")), ] dropdown_choices += available_site_choices onchange = "cmk.sidebar.set_snapin_site(event, %s, this)" % json.dumps( ident) html.dropdown("site", dropdown_choices, deflt=site, onchange=onchange) return only_sites
def page(self): search = get_search_expression() html.begin_form("role", method="POST") # ID forms.header(_("Basic properties"), css="wide") forms.section(_("Internal ID"), simple="builtin" in self._role, is_required=True) if self._role.get("builtin"): html.write_text("%s (%s)" % (self._role_id, _("builtin role"))) html.hidden_field("id", self._role_id) else: html.text_input("id", self._role_id) html.set_focus("id") # Alias forms.section(_("Alias")) html.help(_("An alias or description of the role")) html.text_input("alias", self._role.get("alias", ""), size=50) # Based on if not self._role.get("builtin"): forms.section(_("Based on role")) html.help( _( "Each user defined role is based on one of the builtin roles. " "When created it will start with all permissions of that role. When due to a software " "update or installation of an addons new permissions appear, the user role will get or " "not get those new permissions based on the default settings of the builtin role it's " "based on." ) ) role_choices: Choices = [ (i, r["alias"]) for i, r in self._roles.items() if r.get("builtin") ] html.dropdown( "basedon", role_choices, deflt=self._role.get("basedon", "user"), ordered=True ) forms.end() html.h2(_("Permissions")) # Permissions base_role_id = self._role.get("basedon", self._role_id) html.help( _( "When you leave the permissions at "default" then they get their " "settings from the factory defaults (for builtin roles) or from the " "factory default of their base role (for user define roles). Factory defaults " "may change due to software updates. When choosing another base role, all " "permissions that are on default will reflect the new base role." ) ) for section in permission_section_registry.get_sorted_sections(): # Now filter by the optional search term filtered_perms = [] for perm in permission_registry.get_sorted_permissions(section): if search and ( search not in perm.title.lower() and search not in perm.name.lower() ): continue filtered_perms.append(perm) if not filtered_perms: continue forms.header(section.title, isopen=search is not None, css="wide") for perm in filtered_perms: forms.section(perm.title) pvalue = self._role["permissions"].get(perm.name) def_value = base_role_id in perm.defaults choices: Choices = [ ("yes", _("yes")), ("no", _("no")), ("default", _("default (%s)") % (def_value and _("yes") or _("no"))), ] deflt = {True: "yes", False: "no"}.get(pvalue, "default") html.dropdown("perm_" + perm.name, choices, deflt=deflt, style="width: 130px;") html.help(perm.description) forms.end() html.hidden_fields() html.end_form()
def show(self): if not site_config.is_wato_slave_site(): if not active_config.wato_enabled: html.write_text(_("Setup is disabled.")) return False user_folders = compute_foldertree() # # Render link target selection # # Apply some view specific filters views_to_show: List[Tuple[str, ViewSpec]] = [] dflt_target_name: str = "allhosts" dflt_topic_name: str = "" for name, view in views.get_permitted_views().items(): if (not active_config.visible_views or name in active_config.visible_views) and ( not active_config.hidden_views or name not in active_config.hidden_views ): views_to_show.append((name, view)) if name == dflt_target_name: dflt_topic_name = view["topic"] selected_topic_name: str selected_target_name: str selected_topic_name, selected_target_name = user.load_file( "foldertree", (dflt_topic_name, dflt_target_name) ) visuals_to_show = [("views", e) for e in views_to_show] visuals_to_show += [("dashboards", e) for e in dashboard.get_permitted_dashboards().items()] topics = make_topic_menu(visuals_to_show) topic_choices: Choices = [(topic.title, topic.title) for topic in topics] html.open_table() html.open_tr() html.open_td() html.dropdown( "topic", topic_choices, deflt=selected_topic_name, onchange="cmk.sidebar.wato_tree_topic_changed(this)", ) html.close_td() html.close_tr() html.open_tr() html.open_td() for topic in topics: targets: Choices = [] for item in topic.items: if item.url and item.url.startswith("dashboard.py"): name = "dashboard|" + item.name else: name = item.name targets.append((name, item.title)) if topic.name != selected_topic_name: default = "" style: Optional[str] = "display:none" else: default = selected_target_name style = None html.dropdown( "target_%s" % topic.title, targets, deflt=default, onchange="cmk.sidebar.wato_tree_target_changed(this)", style=style, ) html.close_td() html.close_tr() html.close_table() # Now render the whole tree if user_folders: render_tree_folder( "wato-hosts", list(user_folders.values())[0], "cmk.sidebar.wato_tree_click" ) return None
def render_input(self, varprefix: str, value: str) -> None: html.dropdown(varprefix + "attr_" + self.name(), self._enumlist, value)
def display(self, value: FilterHTTPVariables) -> None: html.dropdown(self.ident, self.choices(), deflt=value.get(self.htmlvars[0], ""))
def page_graph(): host_name = HostName(request.get_str_input_mandatory("host")) service = request.get_str_input_mandatory("service") dsname = request.get_str_input_mandatory("dsname") breadcrumb = make_service_breadcrumb(host_name, service) make_header( html, _("Prediction for %s - %s - %s") % (host_name, service, dsname), breadcrumb, ) # Get current value from perf_data via Livestatus current_value = get_current_perfdata(host_name, service, dsname) prediction_store = prediction.PredictionStore(host_name, service, dsname) timegroup, choices = _load_prediction_information( tg_name=request.var("timegroup"), prediction_store=prediction_store, ) html.begin_form("prediction") html.write_text(_("Show prediction for ")) html.dropdown("timegroup", choices, deflt=timegroup.name, onchange="document.prediction.submit();") html.hidden_fields() html.end_form() # Get prediction data tg_data = prediction_store.get_data(timegroup.name) if tg_data is None: raise MKGeneralException(_("Missing prediction data.")) swapped = swap_and_compute_levels(tg_data, timegroup.params) vertical_range = compute_vertical_range(swapped) legend = [ ("#000000", _("Reference")), ("#ffffff", _("OK area")), ("#ffff00", _("Warning area")), ("#ff0000", _("Critical area")), ] if current_value is not None: legend.append(("#0000ff", _("Current value: %.2f") % current_value)) create_graph(timegroup.name, graph_size, timegroup.range, vertical_range, legend) if "levels_upper" in timegroup.params: render_dual_area(swapped["upper_warn"], swapped["upper_crit"], "#fff000", 0.4) render_area_reverse(swapped["upper_crit"], "#ff0000", 0.1) if "levels_lower" in timegroup.params: render_dual_area(swapped["lower_crit"], swapped["lower_warn"], "#fff000", 0.4) render_area(swapped["lower_crit"], "#ff0000", 0.1) vscala_low = vertical_range[0] vscala_high = vertical_range[1] vert_scala = compute_vertical_scala(vscala_low, vscala_high) time_scala = [[timegroup.range[0] + i * 3600, "%02d:00" % i] for i in range(0, 25, 2)] render_coordinates(vert_scala, time_scala) if "levels_lower" in timegroup.params: render_dual_area(swapped["average"], swapped["lower_warn"], "#ffffff", 0.5) render_curve(swapped["lower_warn"], "#e0e000", square=True) render_curve(swapped["lower_crit"], "#f0b0a0", square=True) if "levels_upper" in timegroup.params: render_dual_area(swapped["upper_warn"], swapped["average"], "#ffffff", 0.5) render_curve(swapped["upper_warn"], "#e0e000", square=True) render_curve(swapped["upper_crit"], "#f0b0b0", square=True) render_curve(swapped["average"], "#000000") render_curve(swapped["average"], "#000000") # repetition makes line bolder # Try to get current RRD data and render it also from_time, until_time = timegroup.range now = time.time() if from_time <= now <= until_time: timeseries = prediction.get_rrd_data(host_name, service, dsname, "MAX", from_time, until_time) rrd_data = timeseries.values render_curve(rrd_data, "#0000ff", 2) if current_value is not None: rel_time = (now - prediction.timezone_at(now)) % timegroup.slice render_point(timegroup.range[0] + rel_time, current_value, "#0000ff") html.footer()
def _preview(self) -> None: html.begin_form("preview", method="POST") self._preview_form() attributes = self._attribute_choices() # first line could be missing in situation of import error csv_reader = self._open_csv_file() if not csv_reader: return # don't try to show preview when CSV could not be read html.h2(_("Preview")) attribute_list = "<ul>%s</ul>" % "".join( ["<li>%s (%s)</li>" % a for a in attributes if a[0] is not None] ) html.help( _( "This list shows you the first 10 rows from your CSV file in the way the import is " "currently parsing it. If the lines are not splitted correctly or the title line is " "not shown as title of the table, you may change the import settings above and try " "again." ) + "<br><br>" + _( "The first row below the titles contains fields to specify which column of the " "CSV file should be imported to which attribute of the created hosts. The import " "progress is trying to match the columns to attributes automatically by using the " "titles found in the title row (if you have some). " "If you use the correct titles, the attributes can be mapped automatically. The " "currently available attributes are:" ) + attribute_list + _( "You can change these assignments according to your needs and then start the " "import by clicking on the <i>Import</i> button above." ) ) # Wenn bei einem Host ein Fehler passiert, dann wird die Fehlermeldung zu dem Host angezeigt, so dass man sehen kann, was man anpassen muss. # Die problematischen Zeilen sollen angezeigt werden, so dass man diese als Block in ein neues CSV-File eintragen kann und dann diese Datei # erneut importieren kann. if self._has_title_line: try: headers = list(next(csv_reader)) except StopIteration: headers = [] # nope, there is no header else: headers = [] rows = list(csv_reader) # Determine how many columns should be rendered by using the longest column num_columns = max([len(r) for r in [headers] + rows]) with table_element( sortable=False, searchable=False, omit_headers=not self._has_title_line ) as table: # Render attribute selection fields table.row() for col_num in range(num_columns): header = headers[col_num] if len(headers) > col_num else None table.cell(escape_to_html_permissive(header)) attribute_varname = "attribute_%d" % col_num if request.var(attribute_varname): attribute_method = request.get_ascii_input_mandatory(attribute_varname) else: attribute_method = self._try_detect_default_attribute(attributes, header) request.del_var(attribute_varname) html.dropdown( "attribute_%d" % col_num, attributes, deflt=attribute_method, autocomplete="off" ) # Render sample rows for row in rows: table.row() for cell in row: table.cell(None, cell) html.end_form()