def page(self) -> PageResult: """Determines the hosts to be shown""" user.need_permission("general.parent_child_topology") topology_settings = TopologySettings() if request.var("filled_in"): # Parameters from the check_mk filters self._update_topology_settings_with_context(topology_settings) elif request.var("host_name"): # Explicit host_name. Used by icon linking to Topology topology_settings.growth_root_nodes = { HostName(html.request.get_str_input_mandatory("host_name")) } else: # Default page without further context topology_settings.growth_root_nodes = self._get_default_view_hostnames( topology_settings.growth_auto_max_nodes ) if request.has_var("topology_settings"): # These parameters are usually generated within javascript through user interactions try: settings_from_var = json.loads(request.get_str_input_mandatory("topology_settings")) for key, value in settings_from_var.items(): setattr(topology_settings, key, value) except (TypeError, ValueError): raise MKGeneralException(_("Invalid topology_settings %r") % topology_settings) self.show_topology(topology_settings)
def action(self) -> ActionResult: varname = request.var("_varname") if not varname: return None action = request.var("_action") config_variable = config_variable_registry[varname]() def_value = self._default_values[varname] if not transactions.check_transaction(): return None if varname in self._current_settings: self._current_settings[ varname] = not self._current_settings[varname] else: self._current_settings[varname] = not def_value msg = _("Changed Configuration variable %s to %s.") % ( varname, "on" if self._current_settings[varname] else "off", ) save_global_settings(self._current_settings) _changes.add_change( "edit-configvar", msg, domains=[config_variable.domain()], need_restart=config_variable.need_restart(), ) if action == "_reset": flash(msg) return redirect(mode_url("globalvars"))
def _from_vars(self): self._timeperiods = watolib.timeperiods.load_timeperiods() self._name = request.var("edit") # missing -> new group # TODO: Nuke the field below? It effectively hides facts about _name for mypy. self._new = self._name is None if self._name in watolib.timeperiods.builtin_timeperiods(): raise MKUserError("edit", _("Builtin timeperiods can not be modified")) if self._new: clone_name = request.var("clone") if request.var("mode") == "import_ical": self._timeperiod = {} elif clone_name: self._name = clone_name self._timeperiod = self._get_timeperiod(self._name) else: # initialize with 24x7 config self._timeperiod = { day: [("00:00", "24:00")] for day in defines.weekday_ids() } else: self._timeperiod = self._get_timeperiod(self._name)
def page(self): check_csrf_token() response.set_content_type("application/json") if not user.may("general.configure_sidebar"): return None snapin_id = request.var("name") if snapin_id is None: return None state = request.var("state") if state not in [ SnapinVisibility.OPEN.value, SnapinVisibility.CLOSED.value, "off" ]: raise MKUserError("state", "Invalid state: %s" % state) user_config = UserSidebarConfig(user, active_config.sidebar) try: snapin = user_config.get_snapin(snapin_id) except KeyError: return None if state == "off": user_config.remove_snapin(snapin) else: snapin.visible = SnapinVisibility(state) user_config.save() return None
def _automation_push_profile(self): site_id = request.var("siteid") if not site_id: raise MKGeneralException(_("Missing variable siteid")) user_id = request.var("user_id") if not user_id: raise MKGeneralException(_("Missing variable user_id")) our_id = omd_site() if our_id is not None and our_id != site_id: raise MKGeneralException( _("Site ID mismatch. Our ID is '%s', but you are saying we are '%s'." ) % (our_id, site_id)) profile = request.var("profile") if not profile: raise MKGeneralException( _("Invalid call: The profile is missing.")) users = userdb.load_users(lock=True) users[UserId(user_id)] = watolib_utils.mk_eval(profile) userdb.save_users(users, datetime.now()) return True
def move_snapin() -> None: response.set_content_type("application/json") if not user.may("general.configure_sidebar"): return None snapin_id = request.var("name") if snapin_id is None: return None user_config = UserSidebarConfig(user, active_config.sidebar) try: snapin = user_config.get_snapin(snapin_id) except KeyError: return None before_id = request.var("before") before_snapin: Optional[UserSidebarSnapin] = None if before_id: try: before_snapin = user_config.get_snapin(before_id) except KeyError: pass user_config.move_snapin_before(snapin, before_snapin) user_config.save() return None
def _ajax_add_bookmark(self) -> None: title = request.var("title") url = request.var("url") if title and url and transactions.transaction_valid(): BookmarkList.validate_url(url, "url") self._add_bookmark(title, url) self.show()
def action(self) -> ActionResult: if not transactions.check_transaction(): return redirect(self.mode_url()) if request.var("_delete"): delid = request.get_ascii_input_mandatory("_delete") if delid not in self._roles: raise MKUserError(None, _("This role does not exist.")) if transactions.transaction_valid() and self._roles[delid].get("builtin"): raise MKUserError(None, _("You cannot delete the builtin roles!")) users = userdb.load_users() for user in users.values(): if delid in user["roles"]: raise MKUserError( None, _("You cannot delete roles, that are still in use (%s)!") % delid, ) self._rename_user_role(delid, None) # Remove from existing users del self._roles[delid] self._save_roles() _changes.add_change( "edit-roles", _("Deleted role '%s'") % delid, sites=get_login_sites() ) elif request.var("_clone"): cloneid = request.get_ascii_input_mandatory("_clone") try: cloned_role = self._roles[cloneid] except KeyError: raise MKUserError(None, _("This role does not exist.")) newid = cloneid while newid in self._roles: newid += "x" new_role = {} new_role.update(cloned_role) new_alias = new_role["alias"] while not groups.is_alias_used("roles", newid, new_alias)[0]: new_alias += _(" (copy)") new_role["alias"] = new_alias if cloned_role.get("builtin"): new_role["builtin"] = False new_role["basedon"] = cloneid self._roles[newid] = new_role self._save_roles() _changes.add_change( "edit-roles", _("Created new role '%s'") % newid, sites=get_login_sites() ) return redirect(self.mode_url())
def handle_actions(self) -> bool: if request.var(self.acknowledge_job_var): self.acknowledge_job() return True if request.var(self.stop_job_var): self.stop_job() return True if request.var(self.delete_job_var): self.delete_job() return True return False
def page_graph_dashlet() -> None: spec = request.var("spec") if not spec: raise MKUserError("spec", _("Missing spec parameter")) graph_identification = json.loads(request.get_str_input_mandatory("spec")) render = request.var("render") if not render: raise MKUserError("render", _("Missing render parameter")) custom_graph_render_options = json.loads( request.get_str_input_mandatory("render")) host_service_graph_dashlet_cmk(graph_identification, custom_graph_render_options)
def action(self) -> ActionResult: folder = Folder.current() if not transactions.check_transaction(): return redirect(mode_url("folder", folder=folder.path())) if request.var("_update_dns_cache") and self._should_use_dns_cache(): user.need_permission("wato.update_dns_cache") update_dns_cache_result = update_dns_cache(self._host.site_id()) infotext = (_("Successfully updated IP addresses of %d hosts.") % update_dns_cache_result.n_updated) if update_dns_cache_result.failed_hosts: infotext += "<br><br><b>Hostnames failed to lookup:</b> " + ", ".join( [ "<tt>%s</tt>" % h for h in update_dns_cache_result.failed_hosts ]) flash(infotext) return None if request.var("delete"): # Delete this host folder.delete_hosts([self._host.name()], automation=delete_hosts) return redirect(mode_url("folder", folder=folder.path())) if request.var("_remove_tls_registration"): remove_tls_registration( {self._host.site_id(): [self._host.name()]}) return None attributes = collect_attributes( "host" if not self._is_cluster() else "cluster", new=False) host = Host.host(self._host.name()) if host is None: flash(f"Host {self._host.name()} could not be found.") return None host.edit(attributes, self._get_cluster_nodes()) self._host = folder.load_host(self._host.name()) if request.var("_save"): return redirect( mode_url("inventory", folder=folder.path(), host=self._host.name())) if request.var("diag_host"): return redirect( mode_url("diag_host", folder=folder.path(), host=self._host.name(), _start_on_load="1")) return redirect(mode_url("folder", folder=folder.path()))
def action(self) -> ActionResult: if not transactions.check_transaction(): return redirect(self.mode_url()) if not request.var("_delete"): return redirect(self.mode_url()) delname = request.var("_delete") for index, attr in enumerate(self._attrs): if attr["name"] == delname: self._attrs.pop(index) save_custom_attrs_to_mk_file(self._all_attrs) self._update_config() _changes.add_change("edit-%sattrs" % self._type, _("Deleted attribute %s") % (delname)) return redirect(self.mode_url())
def _bi_map() -> None: aggr_name = request.var("aggr_name") layout_id = request.var("layout_id") title = _("BI visualization") breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_monitoring(), title) make_header(html, title, breadcrumb) div_id = "node_visualization" html.div("", id=div_id) html.javascript( "node_instance = new cmk.node_visualization.BIVisualization(%s);" % json.dumps(div_id) ) html.javascript( "node_instance.show_aggregations(%s, %s)" % (json.dumps([aggr_name]), json.dumps(layout_id)) )
def action(self) -> ActionResult: if not transactions.check_transaction(): return None vs = self._valuespec() self._connection_cfg = vs.from_html_vars("connection") vs.validate_value(self._connection_cfg, "connection") self._connection_cfg["type"] = "ldap" if self._new: self._connections.insert(0, self._connection_cfg) self._connection_id = self._connection_cfg["id"] else: self._connection_cfg["id"] = self._connection_id self._connections[self._connection_nr] = self._connection_cfg assert self._connection_id is not None if self._new: log_what = "new-ldap-connection" log_text = _("Created new LDAP connection") else: log_what = "edit-ldap-connection" log_text = _("Changed LDAP connection %s") % self._connection_id self._add_change(log_what, log_text) save_connection_config(self._connections) active_config.user_connections = ( self._connections) # make directly available on current page if request.var("_save"): return redirect(mode_url("ldap_config")) # Handle the case where a user hit "Save & Test" during creation return redirect(self.mode_url(_test="1", id=self._connection_id))
def page_handler() -> None: initialize_wato_html_head() if not active_config.wato_enabled: raise MKGeneralException( _("Setup is disabled. Please set <tt>wato_enabled = True</tt>" " in your <tt>multisite.mk</tt> if you want to use Setup.")) # config.current_customer can not be checked with CRE repos if cmk_version.is_managed_edition() and not managed.is_provider( active_config.current_customer): # type: ignore[attr-defined] raise MKGeneralException( _("Check_MK can only be configured on " "the managers central site.")) current_mode = request.var("mode") or "main" mode_permissions, mode_class = _get_mode_permission_and_class(current_mode) display_options.load_from_html(request, html) if display_options.disabled(display_options.N): html.add_body_css_class("inline") # If we do an action, we aquire an exclusive lock on the complete WATO. if transactions.is_transaction(): with store.lock_checkmk_configuration(): _wato_page_handler(current_mode, mode_permissions, mode_class) else: _wato_page_handler(current_mode, mode_permissions, mode_class)
def page(self): check_csrf_token() if not user.may("general.configure_sidebar"): raise MKGeneralException( _("You are not allowed to change the sidebar.")) addname = request.var("name") if addname is None or addname not in snapin_registry: raise MKUserError(None, _("Invalid sidebar element %s") % addname) if addname in _used_snapins(): raise MKUserError(None, _("Element %s is already enabled") % addname) user_config = UserSidebarConfig(user, active_config.sidebar) snapin = UserSidebarSnapin.from_snapin_type_id(addname) user_config.add_snapin(snapin) user_config.save() with output_funnel.plugged(): try: url = SidebarRenderer().render_snapin(snapin) finally: snapin_code = output_funnel.drain() return { "name": addname, "url": url, "content": snapin_code, "refresh": snapin.snapin_type.refresh_regularly(), "restart": snapin.snapin_type.refresh_on_restart(), }
def ajax_set_snapin_site(): response.set_content_type("application/json") ident = request.var("ident") if ident not in snapin_registry: raise MKUserError(None, _("Invalid ident")) site = request.var("site") site_choices = dict([(SiteId(""), _("All sites"))] + user_sites.get_configured_site_choices()) if site not in site_choices: raise MKUserError(None, _("Invalid site")) snapin_sites = user.load_file("sidebar_sites", {}, lock=True) snapin_sites[ident] = site user.save_file("sidebar_sites", snapin_sites)
def _extend_display_dropdown(menu: PageMenu) -> None: display_dropdown = menu.get_dropdown_by_name( "display", make_display_options_dropdown()) context_hidden = request.var("_hidecontext", "no") == "yes" display_dropdown.topics.insert( 0, PageMenuTopic( title=_("Context"), entries=[ PageMenuEntry( title=_("Show context"), icon_name="checkbox" if context_hidden else "checked_checkbox", item=make_simple_link( makeactionuri( request, transactions, [ ("_show_backlog", "no") if context_hidden else ("_hidecontext", "yes"), ], )), ), ], ), )
def action(self) -> ActionResult: delname = request.var("_delete") if not delname: return redirect(mode_url("timeperiods")) if not transactions.check_transaction(): return redirect(mode_url("timeperiods")) if delname in watolib.timeperiods.builtin_timeperiods(): raise MKUserError("_delete", _("Builtin timeperiods can not be modified")) usages = self._find_usages_of_timeperiod(delname) if usages: message = "<b>%s</b><br>%s:<ul>" % ( _("You cannot delete this timeperiod."), _("It is still in use by"), ) for title, link in usages: message += '<li><a href="%s">%s</a></li>\n' % (link, title) message += "</ul>" raise MKUserError(None, message) del self._timeperiods[delname] watolib.timeperiods.save_timeperiods(self._timeperiods) _changes.add_change("edit-timeperiods", _("Deleted timeperiod %s") % delname) return redirect(mode_url("timeperiods"))
def show_log_list(): title = _("All problematic logfiles") breadcrumb = make_simple_page_breadcrumb( mega_menu_registry.menu_monitoring(), title) make_header(html, title, breadcrumb, _log_list_page_menu(breadcrumb)) if request.has_var("_ack") and not request.var("_do_actions") == _("No"): do_log_ack(site=None, host_name=None, file_name=None) return for site, host_name, logs in all_logs(): if not logs: continue all_logs_empty = not any( parse_file(site, host_name, file_name) for file_name in logs) if all_logs_empty: continue # Logfile vanished html.h3( HTMLWriter.render_a( host_name, href=makeuri( request, [("site", site), ("host", host_name)], ), ), class_="table", ) list_logs(site, host_name, logs) html.footer()
def _init_new_host_object(cls): return Host( folder=Folder.current(), host_name=request.var("host"), attributes={}, cluster_nodes=[], )
def get_wato_folder(row: Dict, how: str, with_links: bool = True) -> Union[str, HTML]: filename = row["host_filename"] if not filename.startswith("/wato/") or not filename.endswith("/hosts.mk"): return "" wato_path = filename[6:-9] try: title_path = get_folder_title_path(wato_path, with_links) except MKGeneralException: # happens when a path can not be resolved using the local WATO. # e.g. when having an independent site with different folder # hierarchy added to the GUI. # Display the raw path rather than the exception text. title_path = wato_path.split("/") except Exception as e: return "%s" % e if how == "plain": return title_path[-1] if how == "abs": return HTML(" / ").join(title_path) # We assume that only hosts are show, that are below the current WATO path. # If not then better output absolute path then wrong path. current_path = request.var("wato_folder") if not current_path or not wato_path.startswith(current_path): return HTML(" / ").join(title_path) depth = current_path.count("/") + 1 return HTML(" / ").join(title_path[depth:])
def test_del_vars() -> None: environ = create_environ( query_string="opt_x=x&foo=foo", ) with application_and_request_context(environ): assert html.request.var("opt_x") == "x" assert html.request.var("foo") == "foo" html.request.del_vars(prefix="opt_") assert html.request.var("opt_x") is None assert html.request.var("foo") == "foo" # Check the request local proxied version too assert global_request.var("opt_x") is None assert global_request.var("foo") == "foo"
def action(self) -> ActionResult: if request.var("_reset"): if not transactions.check_transaction(): return None try: del self._current_settings[self._varname] except KeyError: pass msg = escape_to_html( _("Resetted configuration variable %s to its default.") % self._varname) else: new_value = self._valuespec.from_html_vars("ve") self._valuespec.validate_value(new_value, "ve") self._current_settings[self._varname] = new_value msg = HTML( _("Changed global configuration variable %s to %s.") % ( escaping.escape_attribute(self._varname), self._valuespec.value_to_html(new_value), )) self._save() _changes.add_change( "edit-configvar", msg, sites=self._affected_sites(), domains=[self._config_variable.domain()], need_restart=self._config_variable.need_restart(), ) return redirect(self._back_url())
def action(self) -> ActionResult: local_site = omd_site() renamed_host_site = self._host.site_id() if (SiteChanges(SiteChanges.make_path(local_site)).read() or SiteChanges(SiteChanges.make_path(renamed_host_site)).read()): raise MKUserError( "newname", _("You cannot rename a host while you have " "pending changes on the central site (%s) or the " "site the host is monitored on (%s).") % (local_site, renamed_host_site), ) newname = request.var("newname") self._check_new_host_name("newname", newname) # Creating pending entry. That makes the site dirty and that will force a sync of # the config to that site before the automation is being done. host_renaming_job = RenameHostBackgroundJob( self._host, title=_("Renaming of %s -> %s") % (self._host.name(), newname)) renamings = [(Folder.current(), self._host.name(), newname)] host_renaming_job.set_function(rename_hosts_background_job, renamings) try: host_renaming_job.start() except background_job.BackgroundJobAlreadyRunning as e: raise MKGeneralException( _("Another host renaming job is already running: %s") % e) return redirect(host_renaming_job.detail_url())
def get_host_list_links(site: SiteId, hosts: List[Union[str]]) -> List[str]: entries = [] for host in hosts: args: HTTPVariables = [ ("view_name", "hoststatus"), ("site", site), ("host", host), ] if request.var("display_options"): args.append(("display_options", request.var("display_options"))) url = makeuri_contextless(request, args, filename="view.py") link = str(HTMLWriter.render_a(host, href=url)) entries.append(link) return entries
def page(self) -> None: host_names = get_hostnames_from_checkboxes() hosts = { host_name: Folder.current().host(host_name) for host_name in host_names } current_host_hash = sha256(repr(hosts).encode()).hexdigest() # When bulk edit has been made with some hosts, then other hosts have been selected # and then another bulk edit has made, the attributes need to be reset before # rendering the form. Otherwise the second edit will have the attributes of the # first set. host_hash = request.var("host_hash") if not host_hash or host_hash != current_host_hash: request.del_vars(prefix="attr_") request.del_vars(prefix="bulk_change_") html.p("%s%s %s" % ( _("You have selected <b>%d</b> hosts for bulk edit. You can now change " "host attributes for all selected hosts at once. ") % len(hosts), _("If a select is set to <i>don't change</i> then currenty not all selected " "hosts share the same setting for this attribute. " "If you leave that selection, all hosts will keep their individual settings." ), _("In case you want to <i>unset</i> attributes on multiple hosts, you need to " "use the <i>bulk cleanup</i> action instead of bulk edit."), )) html.begin_form("edit_host", method="POST") html.prevent_password_auto_completion() html.hidden_field("host_hash", current_host_hash) configure_attributes(False, hosts, "bulk", parent=Folder.current()) forms.end() html.hidden_fields() html.end_form()
def page(self): user.need_permission("wato.backups") if request.var("job") == "restore": page: backup.PageAbstractBackupJobState = backup.PageBackupRestoreState( ) else: page = ModeBackupJobState() page.show_job_details()
def _authenticate(self): secret = request.var("secret") if not secret: raise MKAuthException(_("Missing secret for automation command.")) if secret != _get_login_secret(): raise MKAuthException(_("Invalid automation secret."))
def _ajax_tag_tree_enter(self): response.set_content_type("application/json") self._load() path = request.get_str_input_mandatory("path").split( "|") if request.var("path") else [] self._cwds[self._current_tree_id] = path self._save_user_settings() response.set_data("OK")