def test_edit_group_missing(web, group_type): group_id = "%s_testgroup_id" % group_type group_alias = "%s_testgroup_alias" % group_type group_alias2 = "%s_testgroup_otheralias" % group_type try: attributes = {"alias": group_alias} if cmk_version.is_managed_edition(): attributes["customer"] = "provider" web.add_group(group_type, group_id, attributes) try: #web.edit_group(group_type, group_id, {"alias": group_alias2}, expect_error = True) web.edit_group(group_type, "%s_missing" % group_id, {"alias": group_alias2}, expect_error=True) except APIError as e: assert str(e) != str(None) return assert False finally: web.delete_group(group_type, group_id)
def test_registered_snapins(): expected_snapins = [ "admin", "admin_mini", "biaggr_groups", "biaggr_groups_tree", "bookmarks", "dashboards", "hostgroups", "master_control", "mkeventd_performance", "nagvis_maps", "performance", "search", "servicegroups", "sitestatus", "speedometer", "tactical_overview", "tag_tree", "time", "views", "wato_folders", "wato_foldertree", ] if not cmk_version.is_raw_edition(): expected_snapins += [ "cmc_stats", "reports", ] if cmk_version.is_managed_edition(): expected_snapins += [ "customers", ] assert sorted(snapin_registry.keys()) == sorted(expected_snapins)
def create_password(params): """Create a password""" user.need_permission("wato.edit") user.need_permission("wato.passwords") body = params["body"] ident = body["ident"] password_details = cast( Password, { k: v for k, v in body.items() if k not in ( "ident", "owned_by", "customer", ) }, ) if version.is_managed_edition(): password_details = update_customer_info(password_details, body["customer"]) password_details[ "owned_by"] = None if body["owned_by"] == "admin" else body["owned_by"] save_password(ident, password_details, new_password=True) return _serve_password(ident, load_password(ident))
def test_edit_cg_group_with_nagvis_maps(web, site): dummy_map_filepath1 = "%s/etc/nagvis/maps/blabla.cfg" % site.root dummy_map_filepath2 = "%s/etc/nagvis/maps/bloblo.cfg" % site.root try: open(dummy_map_filepath1, "w") open(dummy_map_filepath2, "w") attributes = {"alias": "nagvis_test_alias", "nagvis_maps": ["blabla"]} if cmk_version.is_managed_edition(): attributes["customer"] = "provider" web.add_group("contact", "nagvis_test", attributes) attributes["nagvis_maps"] = ["bloblo"] web.edit_group("contact", "nagvis_test", attributes) all_groups = web.get_all_groups("contact") assert "nagvis_test" in all_groups assert "bloblo" in all_groups["nagvis_test"]["nagvis_maps"] finally: web.delete_group("contact", "nagvis_test") os.unlink(dummy_map_filepath1) os.unlink(dummy_map_filepath2)
def _create_snapshots(self): with store.lock_checkmk_configuration(): if not self._changes: raise MKUserError( None, _("Currently there are no changes to activate.")) if self._get_last_change_id() != self._activate_until: raise MKUserError( None, _("Another change has been made in the meantime. Please review it " "to ensure you also want to activate it now and start the " "activation again.")) # Create (legacy) WATO config snapshot start = time.time() logger.debug("Snapshot creation started") # TODO: Remove/Refactor once new changes mechanism has been implemented # This single function is responsible for the slow activate changes (python tar packaging..) snapshot_name = cmk.gui.watolib.snapshots.create_snapshot( self._comment) log_audit(None, "snapshot-created", _("Created snapshot %s") % snapshot_name) if self._activation_id is None: raise Exception("activation ID is not set") work_dir = os.path.join(self.activation_tmp_base_dir, self._activation_id) if cmk_version.is_managed_edition(): import cmk.gui.cme.managed_snapshots as managed_snapshots # pylint: disable=no-name-in-module managed_snapshots.CMESnapshotManager( work_dir, self._get_site_configurations()).generate_snapshots() else: self._generate_snapshots(work_dir) logger.debug("Snapshot creation took %.4f", time.time() - start)
def _login(self, request: Mapping[str, Any]) -> None: site_mgmt = watolib.SiteManagementFactory().factory() all_sites = site_mgmt.load_sites() site = all_sites.get(request["site_id"]) if not site: raise MKUserError(None, _("Site id not found: %s") % request["site_id"]) response = watolib.do_site_login(site, request["username"], request["password"]) if isinstance(response, dict): if cmk_version.is_managed_edition() and response["edition_short"] != "cme": raise MKUserError( None, _( "The Check_MK Managed Services Edition can only " "be connected with other sites using the CME." ), ) secret = response["login_secret"] else: secret = response site["secret"] = secret site_mgmt.save_sites(all_sites)
def test_registered_permissions(): load_dynamic_permissions() expected_permissions = [ "action.acknowledge", "action.addcomment", "action.clearmodattr", "action.customnotification", "action.downtimes", "action.enablechecks", "action.fakechecks", "action.notifications", "action.remove_all_downtimes", "action.reschedule", "action.star", "action.delete_crash_report", "background_jobs.delete_foreign_jobs", "background_jobs.delete_jobs", "background_jobs.manage_jobs", "background_jobs.see_foreign_jobs", "background_jobs.stop_foreign_jobs", "background_jobs.stop_jobs", "bi.see_all", "dashboard.main", "dashboard.simple_problems", "dashboard.checkmk", "dashboard.checkmk_host", "general.acknowledge_werks", "general.act", "general.agent_pairing", "general.change_password", "general.manage_2fa", "general.configure_sidebar", "general.csv_export", "general.delete_foreign_pagetype_topic", "general.edit_pagetype_topic", "general.edit_foreign_pagetype_topic", "general.force_pagetype_topic", "general.publish_pagetype_topic", "general.publish_to_foreign_groups_pagetype_topic", "general.publish_to_groups_pagetype_topic", "general.see_user_pagetype_topic", "general.delete_foreign_bookmark_list", "general.delete_foreign_custom_snapin", "general.delete_foreign_dashboards", "general.delete_foreign_views", "general.disable_notifications", "general.edit_bookmark_list", "general.edit_custom_snapin", "general.edit_dashboards", "general.edit_foreign_bookmark_list", "general.edit_foreign_dashboards", "general.edit_foreign_views", "general.edit_foreign_custom_snapin", "general.edit_notifications", "general.edit_profile", "general.edit_user_attributes", "general.edit_views", "general.force_bookmark_list", "general.force_custom_snapin", "general.force_dashboards", "general.force_views", "general.ignore_hard_limit", "general.ignore_soft_limit", "general.logout", "general.message", "general.painter_options", "general.parent_child_topology", "general.publish_bookmark_list", "general.publish_to_foreign_groups_bookmark_list", "general.publish_to_groups_bookmark_list", "general.publish_custom_snapin", "general.publish_to_foreign_groups_custom_snapin", "general.publish_to_groups_custom_snapin", "general.publish_dashboards", "general.publish_dashboards_to_foreign_groups", "general.publish_dashboards_to_groups", "general.publish_views", "general.publish_views_to_foreign_groups", "general.publish_views_to_groups", "general.see_all", "general.see_availability", "general.see_crash_reports", "general.see_failed_notifications", "general.see_failed_notifications_24h", "general.see_sidebar", "general.see_stales_in_tactical_overview", "general.see_user_bookmark_list", "general.see_user_custom_snapin", "general.see_user_dashboards", "general.see_user_views", "general.server_side_requests", "general.use", "general.view_option_columns", "general.view_option_refresh", "icons_and_actions.action_menu", "icons_and_actions.aggregation_checks", "icons_and_actions.aggregations", "icons_and_actions.check_manpage", "icons_and_actions.check_period", "icons_and_actions.crashed_check", "icons_and_actions.custom_action", "icons_and_actions.download_agent_output", "icons_and_actions.download_snmp_walk", "icons_and_actions.icon_image", "icons_and_actions.inventory", "icons_and_actions.logwatch", "icons_and_actions.mkeventd", "icons_and_actions.notes", "icons_and_actions.perfgraph", "icons_and_actions.prediction", "icons_and_actions.reschedule", "icons_and_actions.rule_editor", "icons_and_actions.stars", "icons_and_actions.status_acknowledged", "icons_and_actions.status_active_checks", "icons_and_actions.status_comments", "icons_and_actions.status_downtimes", "icons_and_actions.status_flapping", "icons_and_actions.status_notification_period", "icons_and_actions.status_notifications_enabled", "icons_and_actions.status_passive_checks", "icons_and_actions.status_service_period", "icons_and_actions.status_stale", "icons_and_actions.wato", "icons_and_actions.parent_child_topology", "mkeventd.actions", "mkeventd.activate", "mkeventd.archive_events_of_hosts", "mkeventd.changestate", "mkeventd.config", "mkeventd.delete", "mkeventd.edit", "mkeventd.see_in_tactical_overview", "mkeventd.seeall", "mkeventd.seeunrelated", "mkeventd.switchmode", "mkeventd.update", "mkeventd.update_comment", "mkeventd.update_contact", "nagvis.*_*_*", "nagvis.Map_delete", "nagvis.Map_delete_*", "nagvis.Map_edit", "nagvis.Map_edit_*", "nagvis.Map_view", "nagvis.Map_view_*", "nagvis.Rotation_view_*", "notification_plugin.asciimail", "notification_plugin.cisco_webex_teams", "notification_plugin.jira_issues", "notification_plugin.mail", "notification_plugin.mkeventd", "notification_plugin.opsgenie_issues", "notification_plugin.pagerduty", "notification_plugin.pushover", "notification_plugin.servicenow", "notification_plugin.signl4", "notification_plugin.ilert", "notification_plugin.slack", "notification_plugin.sms", "notification_plugin.sms_api", "notification_plugin.spectrum", "notification_plugin.victorops", "sidesnap.admin_mini", "sidesnap.biaggr_groups", "sidesnap.biaggr_groups_tree", "sidesnap.bookmarks", "sidesnap.dashboards", "sidesnap.hostgroups", "sidesnap.master_control", "sidesnap.mkeventd_performance", "sidesnap.nagvis_maps", "sidesnap.performance", "sidesnap.search", "sidesnap.servicegroups", "sidesnap.sitestatus", "sidesnap.speedometer", "sidesnap.tactical_overview", "sidesnap.tag_tree", "sidesnap.time", "sidesnap.views", "sidesnap.wato_foldertree", "view.aggr_all", "view.aggr_all_api", "view.aggr_group", "view.aggr_host", "view.aggr_hostgroup_boxed", "view.aggr_hostnameaggrs", "view.aggr_hostproblems", "view.aggr_problems", "view.aggr_service", "view.aggr_single", "view.aggr_single_api", "view.aggr_singlehost", "view.aggr_singlehosts", "view.aggr_summary", "view.alerthandlers", "view.alertstats", "view.allhosts", "view.allservices", "view.bi_map_hover_host", "view.bi_map_hover_service", "view.api_downtimes", "view.comments", "view.comments_of_host", "view.comments_of_service", "view.contactnotifications", "view.crash_reports", "view.downtime_history", "view.downtimes", "view.downtimes_of_host", "view.downtimes_of_service", "view.docker_containers", "view.docker_nodes", "view.vpshere_vms", "view.vsphere_servers", "view.ec_event", "view.ec_event_mobile", "view.ec_events", "view.ec_events_mobile", "view.ec_events_of_host", "view.ec_events_of_monhost", "view.ec_history_of_event", "view.ec_history_of_host", "view.ec_history_recent", "view.ec_historyentry", "view.events", "view.events_dash", "view.failed_notifications", "view.host", "view.host_crit", "view.host_dt_hist", "view.host_export", "view.host_ok", "view.host_pending", "view.host_unknown", "view.host_warn", "view.hostevents", "view.hostgroup", "view.hostgroup_up", "view.hostgroup_down", "view.hostgroup_unreach", "view.hostgroup_pend", "view.hostgroups", "view.hostgroupservices", "view.hostgroupservices_ok", "view.hostgroupservices_warn", "view.hostgroupservices_crit", "view.hostgroupservices_unknwn", "view.hostgroupservices_pend", "view.hostnotifications", "view.hostpnp", "view.hostproblems", "view.hostproblems_dash", "view.hosts", "view.hoststatus", "view.hostsvcevents", "view.hostsvcnotifications", "view.inv_host", "view.inv_host_history", "view.inv_hosts_cpu", "view.inv_hosts_ports", "view.invbackplane_of_host", "view.invbackplane_search", "view.invchassis_of_host", "view.invchassis_search", "view.invcmksites_of_host", "view.invcmksites_search", "view.invcmkversions_of_host", "view.invcmkversions_search", "view.invcontainer_of_host", "view.invcontainer_search", "view.invdockercontainers_of_host", "view.invdockercontainers_search", "view.invdockerimages_of_host", "view.invdockerimages_search", "view.invfan_of_host", "view.invfan_search", "view.invibmmqchannels_of_host", "view.invibmmqchannels_search", "view.invibmmqmanagers_of_host", "view.invibmmqmanagers_search", "view.invibmmqqueues_of_host", "view.invibmmqqueues_search", "view.invinterface_of_host", "view.invinterface_search", "view.invkernelconfig_of_host", "view.invkernelconfig_search", "view.invmodule_of_host", "view.invmodule_search", "view.invoradataguardstats_of_host", "view.invoradataguardstats_search", "view.invorainstance_of_host", "view.invorainstance_search", "view.invorarecoveryarea_of_host", "view.invorarecoveryarea_search", "view.invorasga_of_host", "view.invorasga_search", "view.invorapga_of_host", "view.invorapga_search", "view.invoratablespace_of_host", "view.invoratablespace_search", "view.invorasystemparameter_of_host", "view.invorasystemparameter_search", "view.invother_of_host", "view.invother_search", "view.invpsu_of_host", "view.invpsu_search", "view.invsensor_of_host", "view.invsensor_search", "view.invstack_of_host", "view.invstack_search", "view.invswpac_of_host", "view.invswpac_search", "view.invtunnels_of_host", "view.invtunnels_search", "view.invunknown_of_host", "view.invunknown_search", "view.logfile", "view.mobile_contactnotifications", "view.mobile_events", "view.mobile_host", "view.mobile_hostproblems", "view.mobile_hostproblems_unack", "view.mobile_hoststatus", "view.mobile_hostsvcevents", "view.mobile_hostsvcnotifications", "view.mobile_notifications", "view.mobile_searchhost", "view.mobile_searchsvc", "view.mobile_service", "view.mobile_svcevents", "view.mobile_svcnotifications", "view.mobile_svcproblems", "view.mobile_svcproblems_unack", "view.nagstamon_hosts", "view.nagstamon_svc", "view.notifications", "view.pending_discovery", "view.pendingsvc", "view.perf_matrix", "view.perf_matrix_search", "view.problemsofhost", "view.recentsvc", "view.searchhost", "view.searchpnp", "view.searchsvc", "view.service", "view.service_check_durations", "view.servicedesc", "view.servicedescpnp", "view.servicegroup", "view.sitehosts", "view.sitesvcs", "view.sitesvcs_crit", "view.sitesvcs_ok", "view.sitesvcs_pend", "view.sitesvcs_unknwn", "view.sitesvcs_warn", "view.stale_hosts", "view.svc_dt_hist", "view.svcevents", "view.svcgroups", "view.svcnotifications", "view.svcproblems", "view.svcproblems_dash", "view.topology_hover_host", "view.topology_filters", "view.uncheckedsvc", "view.unmonitored_services", "wato.activate", "wato.activateforeign", "wato.add_or_modify_executables", "wato.all_folders", "wato.analyze_config", "wato.api_allowed", "wato.auditlog", "wato.automation", "wato.backups", "wato.bi_admin", "wato.bi_rules", "wato.check_plugins", "wato.clear_auditlog", "wato.clone_hosts", "wato.custom_attributes", "wato.diag_host", "wato.diagnostics", "wato.download_agent_output", "wato.download_agents", "wato.edit", "wato.edit_all_passwords", "wato.edit_all_predefined_conditions", "wato.edit_folders", "wato.edit_hosts", "wato.global", "wato.groups", "wato.hosts", "wato.hosttags", "wato.icons", "wato.manage_folders", "wato.manage_hosts", "wato.move_hosts", "wato.notifications", "wato.parentscan", "wato.passwords", "wato.pattern_editor", "wato.random_hosts", "wato.rename_hosts", "wato.rulesets", "wato.see_all_folders", "wato.seeall", "wato.service_discovery_to_ignored", "wato.service_discovery_to_monitored", "wato.service_discovery_to_removed", "wato.service_discovery_to_undecided", "wato.services", "wato.set_read_only", "wato.sites", "wato.snapshots", "wato.timeperiods", "wato.update_dns_cache", "wato.use", "wato.users", "wato.show_last_user_activity", "view.cmk_servers", "view.cmk_sites", "view.cmk_sites_of_host", "view.host_graphs", "view.service_graphs", ] if not cmk_version.is_raw_edition(): expected_permissions += [ "agent_registration.edit", "dashboard.linux_hosts_overview", "dashboard.linux_single_overview", "dashboard.windows_hosts_overview", "dashboard.windows_single_overview", "dashboard.problems", "dashboard.site", "dashboard.ntop_alerts", "dashboard.ntop_flows", "dashboard.ntop_top_talkers", "general.edit_reports", "icons_and_actions.agent_deployment", "icons_and_actions.status_shadow", "report.bi_availability", "report.default", "report.host", "report.instant", "report.instant_availability", "report.instant_graph_collection", "report.instant_view", "report.service_availability", "report.host_performance_graphs", "sidesnap.cmc_stats", "sidesnap.reports", "view.allhosts_deploy", "view.ntop_interfaces", "wato.agent_deploy_custom_files", "wato.agent_deployment", "wato.agents", "wato.alert_handlers", "wato.bake_agents", "wato.dcd_connections", "wato.download_all_agents", "wato.license_usage", "wato.influxdb_connections", "wato.submit_license_usage", "wato.manage_mkps", "wato.mkps", "wato.sign_agents", "general.delete_foreign_custom_graph", "general.delete_foreign_forecast_graph", "general.delete_foreign_graph_collection", "general.delete_foreign_graph_tuning", "general.delete_foreign_reports", "general.delete_foreign_sla_configuration", "general.delete_foreign_stored_report", "general.delete_stored_report", "general.edit_custom_graph", "general.edit_forecast_graph", "general.edit_foreign_forecast_graph", "general.edit_foreign_custom_graph", "general.edit_foreign_graph_collection", "general.edit_foreign_graph_tuning", "general.edit_foreign_reports", "general.edit_foreign_sla_configuration", "general.edit_graph_collection", "general.edit_graph_tuning", "general.edit_sla_configuration", "general.force_custom_graph", "general.publish_forecast_graph", "general.force_graph_collection", "general.force_graph_tuning", "general.publish_graph_collection", "general.publish_to_foreign_groups_graph_collection", "general.publish_to_groups_graph_collection", "general.publish_graph_tuning", "general.publish_to_foreign_groups_graph_tuning", "general.publish_to_groups_graph_tuning", "general.publish_reports", "general.publish_reports_to_foreign_groups", "general.publish_reports_to_groups", "general.publish_sla_configuration", "general.publish_to_foreign_groups_sla_configuration", "general.publish_to_groups_sla_configuration", "general.publish_stored_report", "general.publish_to_foreign_groups_forecast_graph", "general.publish_to_groups_forecast_graph", "general.see_user_custom_graph", "general.see_user_forecast_graph", "general.see_user_graph_collection", "general.see_user_graph_tuning", "general.see_user_reports", "general.see_user_sla_configuration", "general.see_user_stored_report", "general.reporting", "general.schedule_reports", "general.schedule_reports_all", "general.force_forecast_graph", "general.force_reports", "general.force_sla_configuration", "general.instant_reports", "general.publish_custom_graph", "general.publish_to_foreign_groups_custom_graph", "general.publish_to_groups_custom_graph", "icons_and_actions.deployment_status", "icons_and_actions.ntop_host", ] if cmk_version.is_managed_edition(): expected_permissions += [ "wato.customer_management", "view.customers", "view.customer_hosts", "view.customer_hosts_up", "view.customer_hosts_down", "view.customer_hosts_pend", "view.customer_hosts_unreach", "sidesnap.customers", ] assert sorted(expected_permissions) == sorted(permission_registry.keys()) for perm in permission_registry.values(): assert isinstance(perm.description, (str, LazyString)) assert isinstance(perm.title, (str, LazyString)) assert isinstance(perm.defaults, list)
# -*- coding: utf-8 -*- # Copyright (C) 2020 tribe29 GmbH - License: GNU General Public License v2 # This file is part of Checkmk (https://checkmk.com). It is subject to the terms and # conditions defined in the file COPYING, which is part of this source code package. import json import random import string import pytest from tests.unit.cmk.gui.conftest import WebTestAppForCMK from cmk.utils import version managedtest = pytest.mark.skipif(not version.is_managed_edition(), reason="see #7213") @managedtest @pytest.mark.parametrize("group_type", ["host", "contact", "service"]) def test_openapi_groups(group_type, aut_user_auth_wsgi_app: WebTestAppForCMK): name = _random_string(10) alias = _random_string(10) group = {"name": name, "alias": alias, "customer": "provider"} base = "/NO_SITE/check_mk/api/1.0" resp = aut_user_auth_wsgi_app.call_method( "post",
def page(self): # Let exceptions from loading notification scripts happen now watolib.load_notification_scripts() html.begin_form("user", method="POST") html.prevent_password_auto_completion() forms.header(_("Identity")) # ID forms.section(_("Username"), simple=not self._is_new_user) if self._is_new_user: vs_user_id = UserID(allow_empty=False) else: vs_user_id = FixedValue(self._user_id) vs_user_id.render_input("user_id", self._user_id) def lockable_input(name, dflt): if not self._is_locked(name): html.text_input(name, self._user.get(name, dflt), size=50) else: html.write_text(self._user.get(name, dflt)) html.hidden_field(name, self._user.get(name, dflt)) # Full name forms.section(_("Full name")) lockable_input('alias', self._user_id) html.help(_("Full name or alias of the user")) # Email address forms.section(_("Email address")) email = self._user.get("email", "") if not self._is_locked("email"): EmailAddress().render_input("email", email) else: html.write_text(email) html.hidden_field("email", email) html.help( _("The email address is optional and is needed " "if the user is a monitoring contact and receives notifications " "via Email.")) forms.section(_("Pager address")) lockable_input('pager', '') html.help(_("The pager address is optional ")) if cmk_version.is_managed_edition(): forms.section(self._vs_customer.title()) self._vs_customer.render_input("customer", managed.get_customer_id(self._user)) html.help(self._vs_customer.help()) vs_sites = self._vs_sites() forms.section(vs_sites.title()) authorized_sites = self._user.get("authorized_sites", vs_sites.default_value()) if not self._is_locked("authorized_sites"): vs_sites.render_input("authorized_sites", authorized_sites) else: html.write_html(vs_sites.value_to_text(authorized_sites)) html.help(vs_sites.help()) self._show_custom_user_attributes('ident') forms.header(_("Security")) forms.section(_("Authentication")) is_automation = self._user.get("automation_secret", None) is not None html.radiobutton("authmethod", "password", not is_automation, _("Normal user login with password")) html.open_ul() html.open_table() html.open_tr() html.td(_("password:"******"_password_" + self._pw_suffix(), autocomplete="new-password") html.close_td() html.close_tr() html.open_tr() html.td(_("repeat:")) html.open_td() html.password_input("_password2_" + self._pw_suffix(), autocomplete="new-password") html.write_text(" (%s)" % _("optional")) html.close_td() html.close_tr() html.open_tr() html.td("%s:" % _("Enforce change")) html.open_td() # Only make password enforcement selection possible when user is allowed to change the PW uid = None if self._user_id is None else UserId(self._user_id) if (self._is_new_user or (config.user_may(uid, 'general.edit_profile') and config.user_may(uid, 'general.change_password'))): html.checkbox( "enforce_pw_change", self._user.get("enforce_pw_change", False), label=_("Change password at next login or access")) else: html.write_text( _("Not permitted to change the password. Change can not be enforced." )) else: html.i( _('The password can not be changed (It is locked by the user connector).' )) html.hidden_field('_password', '') html.hidden_field('_password2', '') html.close_td() html.close_tr() html.close_table() html.close_ul() html.radiobutton("authmethod", "secret", is_automation, _("Automation secret for machine accounts")) html.open_ul() html.text_input("_auth_secret", self._user.get("automation_secret", ""), size=30, id_="automation_secret") html.write_text(" ") html.open_b(style=["position: relative", "top: 4px;"]) html.write(" ") html.icon_button( "javascript:cmk.wato.randomize_secret('automation_secret', 20);", _("Create random secret"), "random") html.close_b() html.close_ul() html.help( _("If you want the user to be able to login " "then specify a password here. Users without a login make sense " "if they are monitoring contacts that are just used for " "notifications. The repetition of the password is optional. " "<br>For accounts used by automation processes (such as fetching " "data from views for further procession), set the method to " "<u>secret</u>. The secret will be stored in a local file. Processes " "with read access to that file will be able to use Multisite as " "a webservice without any further configuration.")) # Locking forms.section(_("Disable password"), simple=True) if not self._is_locked('locked'): html.checkbox("locked", self._user.get("locked", False), label=_("disable the login to this account")) else: html.write_text( _('Login disabled') if self._user. get("locked", False) else _('Login possible')) html.hidden_field('locked', '1' if self._user.get("locked", False) else '') html.help( _("Disabling the password will prevent a user from logging in while " "retaining the original password. Notifications are not affected " "by this setting.")) forms.section(_("Idle timeout")) idle_timeout = self._user.get("idle_timeout") if not self._is_locked("idle_timeout"): watolib.get_vs_user_idle_timeout().render_input( "idle_timeout", idle_timeout) else: html.write_text(idle_timeout) html.hidden_field("idle_timeout", idle_timeout) # Roles forms.section(_("Roles")) is_member_of_at_least_one = False for role_id, role in sorted(self._roles.items(), key=lambda x: (x[1]["alias"], x[0])): if not self._is_locked("roles"): html.checkbox("role_" + role_id, role_id in self._user.get("roles", [])) url = watolib.folder_preserving_link([("mode", "edit_role"), ("edit", role_id)]) html.a(role["alias"], href=url) html.br() else: is_member = role_id in self._user.get("roles", []) if is_member: is_member_of_at_least_one = True url = watolib.folder_preserving_link([("mode", "edit_role"), ("edit", role_id)]) html.a(role["alias"], href=url) html.br() html.hidden_field("role_" + role_id, '1' if is_member else '') if self._is_locked('roles') and not is_member_of_at_least_one: html.i(_('No roles assigned.')) self._show_custom_user_attributes('security') # Contact groups forms.header(_("Contact Groups"), isopen=False) forms.section() groups_page_url = watolib.folder_preserving_link([("mode", "contact_groups")]) group_assign_url = watolib.folder_preserving_link([ ("mode", "rulesets"), ("group", "grouping") ]) if not self._contact_groups: html.write( _("Please first create some <a href='%s'>contact groups</a>") % groups_page_url) else: entries = sorted([(group['alias'] or c, c) for c, group in self._contact_groups.items()]) is_member_of_at_least_one = False for alias, gid in entries: is_member = gid in self._user.get("contactgroups", []) if not self._is_locked('contactgroups'): html.checkbox("cg_" + gid, gid in self._user.get("contactgroups", [])) else: if is_member: is_member_of_at_least_one = True html.hidden_field("cg_" + gid, '1' if is_member else '') if not self._is_locked('contactgroups') or is_member: url = watolib.folder_preserving_link([ ("mode", "edit_contact_group"), ("edit", gid) ]) html.a(alias, href=url) html.br() if self._is_locked( 'contactgroups') and not is_member_of_at_least_one: html.i(_('No contact groups assigned.')) html.help( _("Contact groups are used to assign monitoring " "objects to users. If you haven't defined any contact groups yet, " "then first <a href='%s'>do so</a>. Hosts and services can be " "assigned to contact groups using <a href='%s'>rules</a>.<br><br>" "If you do not put the user into any contact group " "then no monitoring contact will be created for the user.") % (groups_page_url, group_assign_url)) forms.header(_("Notifications"), isopen=False) if not self._rbn_enabled(): forms.section(_("Enabling"), simple=True) html.checkbox("notifications_enabled", self._user.get("notifications_enabled", False), label=_("enable notifications")) html.help( _("Notifications are sent out " "when the status of a host or service changes.")) # Notification period forms.section(_("Notification time period")) user_np = self._user.get("notification_period") if not isinstance(user_np, str): raise Exception("invalid notification period %r" % (user_np, )) html.dropdown("notification_period", [(id_, "%s" % (tp["alias"])) for (id_, tp) in self._timeperiods.items()], deflt=user_np, ordered=True) html.help( _("Only during this time period the " "user will get notifications about host or service alerts.")) # Notification options notification_option_names = { # defined here: _() must be executed always! "host": { "d": _("Host goes down"), "u": _("Host gets unreachble"), "r": _("Host goes up again"), }, "service": { "w": _("Service goes into warning state"), "u": _("Service goes into unknown state"), "c": _("Service goes into critical state"), "r": _("Service recovers to OK"), }, "both": { "f": _("Start or end of flapping state"), "s": _("Start or end of a scheduled downtime"), } } forms.section(_("Notification Options")) for title, what, opts in [(_("Host events"), "host", "durfs"), (_("Service events"), "service", "wucrfs")]: html.write_text("%s:" % title) html.open_ul() user_opts = self._user.get(what + "_notification_options", opts) for opt in opts: opt_name = notification_option_names[what].get( opt, notification_option_names["both"].get(opt)) html.checkbox(what + "_" + opt, opt in user_opts, label=opt_name) html.br() html.close_ul() html.help( _("Here you specify which types of alerts " "will be notified to this contact. Note: these settings will only be saved " "and used if the user is member of a contact group.")) forms.section(_("Notification Method")) watolib.get_vs_flexible_notifications().render_input( "notification_method", self._user.get("notification_method")) else: forms.section(_("Fallback notifications"), simple=True) html.checkbox("fallback_contact", self._user.get("fallback_contact", False), label=_("Receive fallback notifications")) html.help( _("In case none of your notification rules handles a certain event a notification " "will be sent to this contact. This makes sure that in that case at least <i>someone</i> " "gets notified. Furthermore this contact will be used for notifications to any host or service " "that is not known to the monitoring. This can happen when you forward notifications " "from the Event Console.<br><br>Notification fallback can also configured in the global " "setting <a href=\"wato.py?mode=edit_configvar&varname=notification_fallback_email\">" "Fallback email address for notifications</a>.")) self._show_custom_user_attributes('notify') forms.header(_("Personal Settings"), isopen=False) select_language(self._user) self._show_custom_user_attributes('personal') # Later we could add custom macros here, which then could be used # for notifications. On the other hand, if we implement some check_mk # --notify, we could directly access the data in the account with the need # to store values in the monitoring core. We'll see what future brings. forms.end() html.button("save", _("Save")) if self._is_new_user: html.set_focus("user_id") else: html.set_focus("alias") html.hidden_fields() html.end_form()
def group_edit_details(body): group_details = {k: v for k, v in body.items() if k != "customer"} if version.is_managed_edition() and "customer" in body: group_details = update_customer_info(group_details, body["customer"]) return group_details
def event_rule_matches_non_inverted(rule_pack, rule, event): if not match_ipv4_network(rule.get("match_ipaddress", "0.0.0.0/0"), event["ipaddress"]): return _("The source IP address does not match.") if match(rule.get("match_host"), event["host"], complete=True) is False: return _("The host name does not match.") if match(rule.get("match_application"), event["application"], complete=False) is False: return _("The application (syslog tag) does not match") if "match_facility" in rule and event["facility"] != rule["match_facility"]: return _("The syslog facility does not match") # First try cancelling rules if "match_ok" in rule or "cancel_priority" in rule: if "cancel_priority" in rule: up, lo = rule["cancel_priority"] cp = event["priority"] >= lo and event["priority"] <= up else: cp = True match_groups = match(rule.get("match_ok", ""), event["text"], complete=False) if match_groups is not False and cp: if match_groups is True: match_groups = () return True, match_groups try: match_groups = match(rule.get("match"), event["text"], complete=False) except Exception as e: return _("Invalid regular expression: %s") % e if match_groups is False: return _("The message text does not match the required pattern.") if "match_priority" in rule: prio_from, prio_to = rule["match_priority"] if prio_from > prio_to: prio_to, prio_from = prio_from, prio_to p = event["priority"] if p < prio_from or p > prio_to: return _("The syslog priority is not in the required range.") if "match_sl" in rule: sl_from, sl_to = rule["match_sl"] if sl_from > sl_to: sl_to, sl_from = sl_from, sl_to p = event.get("sl") if p is None: return _("No service level is set in event") if p < sl_from or p > sl_to: return _("Wrong service level %d (need %d..%d)") % (p, sl_from, sl_to) if "match_timeperiod" in rule: reason = check_timeperiod(rule["match_timeperiod"]) if reason: return reason if cmk_version.is_managed_edition(): import cmk.gui.cme.managed as managed # pylint: disable=no-name-in-module if "customer" in rule_pack: rule_customer_id = rule_pack["customer"] else: rule_customer_id = rule.get("customer", managed.SCOPE_GLOBAL) site_customer_id = managed.get_customer_id(config.sites[event["site"]]) if rule_customer_id != managed.SCOPE_GLOBAL and site_customer_id != rule_customer_id: return _("Wrong customer") if match_groups is True: match_groups = () # no matching groups return False, match_groups
def test_generate_pre_17_site_snapshot(edition_short, monkeypatch, tmp_path, with_user_login, remote_site): snapshot_data_collector_class = ("CMESnapshotDataCollector" if edition_short == "cme" else "CRESnapshotDataCollector") is_pre_17_site = True monkeypatch.setattr(cmk_version, "edition_short", lambda: edition_short) monkeypatch.setattr(utils, "is_pre_17_remote_site", lambda s: is_pre_17_site) activation_manager = _get_activation_manager(monkeypatch, remote_site) snapshot_settings = _create_sync_snapshot( activation_manager, snapshot_data_collector_class, monkeypatch, tmp_path, is_pre_17_site, remote_site, ) # And now check the resulting snapshot contents unpack_dir = tmp_path / "snapshot_unpack" if unpack_dir.exists(): shutil.rmtree(str(unpack_dir)) with tarfile.open(snapshot_settings.snapshot_path, "r") as t: t.extractall(str(unpack_dir)) expected_subtars = [ "auth.secret.tar", "auth.serials.tar", "check_mk.tar", "diskspace.tar", "htpasswd.tar", "mkeventd_mkp.tar", "mkeventd.tar", "multisite.tar", "sitespecific.tar", "usersettings.tar", ] if is_enterprise_repo(): expected_subtars += [ "dcd.tar", "mknotify.tar", ] if config.sites[remote_site].get("replicate_mkps", False): expected_subtars += [ "local.tar", "mkps.tar", ] if not cmk_version.is_raw_edition(): expected_subtars.append("liveproxyd.tar") if cmk_version.is_managed_edition(): expected_subtars += [ "customer_check_mk.tar", "customer_gui_design.tar", "customer_multisite.tar", "gui_logo.tar", "gui_logo_dark.tar", "gui_logo_facelift.tar", ] assert sorted(f.name for f in unpack_dir.iterdir()) == sorted(expected_subtars) expected_files: Dict[str, List[str]] = { "mkeventd_mkp.tar": [], "multisite.tar": ["global.mk", "users.mk"], "usersettings.tar": [with_user_login], "mkeventd.tar": [], "check_mk.tar": ["hosts.mk", "contacts.mk"], "htpasswd.tar": ["htpasswd"], "liveproxyd.tar": [], "sitespecific.tar": ["sitespecific.mk"], "auth.secret.tar": [], "dcd.tar": [], "auth.serials.tar": ["auth.serials"], "mknotify.tar": [], "diskspace.tar": [], } if config.sites[remote_site].get("replicate_mkps", False): expected_files.update({"local.tar": [], "mkps.tar": []}) if cmk_version.is_managed_edition(): expected_files.update({ "customer_check_mk.tar": ["customer.mk"], "customer_gui_design.tar": [], "customer_multisite.tar": ["customer.mk"], "gui_logo.tar": [], "gui_logo_dark.tar": [], "gui_logo_facelift.tar": [], # TODO: Shouldn't we clean up these subtle differences? "mkeventd.tar": ["rules.mk"], "check_mk.tar": ["groups.mk", "contacts.mk"], "multisite.tar": [ "bi.mk", "customers.mk", "global.mk", "groups.mk", "user_connections.mk", "users.mk", ], }) if not cmk_version.is_raw_edition(): expected_files["liveproxyd.tar"] = [] # And now check the subtar contents for subtar in unpack_dir.iterdir(): subtar_unpack_dir = unpack_dir / subtar.stem subtar_unpack_dir.mkdir(parents=True, exist_ok=True) with tarfile.open(str(subtar), "r") as s: s.extractall(str(subtar_unpack_dir)) files = sorted( str(f.relative_to(subtar_unpack_dir)) for f in subtar_unpack_dir.iterdir()) assert sorted(expected_files[subtar.name]) == files, ( "Subtar %s has wrong files" % subtar.name)
def get_host_attributes(hostname: HostName, config_cache: ConfigCache) -> ObjectAttributes: host_config = config_cache.get_host_config(hostname) attrs = host_config.extra_host_attributes # Pre 1.6 legacy attribute. We have changed our whole code to use the # livestatus column "tags" which is populated by all attributes starting with # "__TAG_" instead. We may deprecate this is one day. attrs["_TAGS"] = " ".join( sorted(config_cache.get_host_config(hostname).tags)) attrs.update(_get_tag_attributes(host_config.tag_groups, "TAG")) attrs.update(_get_tag_attributes(host_config.labels, "LABEL")) attrs.update(_get_tag_attributes(host_config.label_sources, "LABELSOURCE")) if "alias" not in attrs: attrs["alias"] = host_config.alias # Now lookup configured IP addresses v4address: Optional[str] = None if host_config.is_ipv4_host: v4address = ip_address_of(host_config, 4) if v4address is None: v4address = "" attrs["_ADDRESS_4"] = v4address v6address: Optional[str] = None if host_config.is_ipv6_host: v6address = ip_address_of(host_config, 6) if v6address is None: v6address = "" attrs["_ADDRESS_6"] = v6address ipv6_primary = host_config.is_ipv6_primary if ipv6_primary: attrs["address"] = attrs["_ADDRESS_6"] attrs["_ADDRESS_FAMILY"] = "6" else: attrs["address"] = attrs["_ADDRESS_4"] attrs["_ADDRESS_FAMILY"] = "4" add_ipv4addrs, add_ipv6addrs = host_config.additional_ipaddresses if add_ipv4addrs: attrs["_ADDRESSES_4"] = " ".join(add_ipv4addrs) for nr, ipv4_address in enumerate(add_ipv4addrs): key = "_ADDRESS_4_%s" % (nr + 1) attrs[key] = ipv4_address if add_ipv6addrs: attrs["_ADDRESSES_6"] = " ".join(add_ipv6addrs) for nr, ipv6_address in enumerate(add_ipv6addrs): key = "_ADDRESS_6_%s" % (nr + 1) attrs[key] = ipv6_address # Add the optional WATO folder path path = config.host_paths.get(hostname) if path: attrs["_FILENAME"] = path # Add custom user icons and actions actions = host_config.icons_and_actions if actions: attrs["_ACTIONS"] = ",".join(actions) if cmk_version.is_managed_edition(): attrs[ "_CUSTOMER"] = config.current_customer # type: ignore[attr-defined] return attrs
def has_custom_logo() -> bool: return cmk_version.is_managed_edition() and customers.get( current_customer, {}).get("globals", {}).get("logo")
def _expected_replication_paths(): expected = [ ReplicationPath('dir', 'check_mk', 'etc/check_mk/conf.d/wato/', []), ReplicationPath('dir', 'multisite', 'etc/check_mk/multisite.d/wato/', []), ReplicationPath('file', 'htpasswd', 'etc/htpasswd', []), ReplicationPath('file', 'auth.secret', 'etc/auth.secret', []), ReplicationPath('file', 'auth.serials', 'etc/auth.serials', []), ReplicationPath('dir', 'usersettings', 'var/check_mk/web', ['*/report-thumbnails']), ReplicationPath('dir', 'mkps', 'var/check_mk/packages', []), ReplicationPath('dir', 'local', 'local', []), ] if not cmk_version.is_raw_edition(): expected += [ ReplicationPath('dir', 'liveproxyd', 'etc/check_mk/liveproxyd.d/wato/', []), ] if testlib.is_enterprise_repo(): expected += [ ReplicationPath('dir', 'dcd', 'etc/check_mk/dcd.d/wato/', []), ReplicationPath('dir', 'mknotify', 'etc/check_mk/mknotifyd.d/wato', []), ] expected += [ ReplicationPath('dir', 'mkeventd', 'etc/check_mk/mkeventd.d/wato', []), ReplicationPath('dir', 'mkeventd_mkp', 'etc/check_mk/mkeventd.d/mkp/rule_packs', []), ReplicationPath('file', 'diskspace', 'etc/diskspace.conf', []), ] if cmk_version.is_managed_edition(): expected += [ ReplicationPath(ty='file', ident='customer_check_mk', site_path='etc/check_mk/conf.d/customer.mk', excludes=[]), ReplicationPath(ty='file', ident='customer_gui_design', site_path='etc/check_mk/multisite.d/zzz_customer_gui_design.mk', excludes=[]), ReplicationPath(ty='file', ident='customer_multisite', site_path='etc/check_mk/multisite.d/customer.mk', excludes=[]), ReplicationPath( ty='file', ident='gui_logo', site_path='local/share/check_mk/web/htdocs/themes/classic/images/sidebar_top.png', excludes=[]), ReplicationPath( ty='file', ident='gui_logo_dark', site_path='local/share/check_mk/web/htdocs/themes/modern-dark/images/mk-logo.png', excludes=[]), ReplicationPath( ty='file', ident='gui_logo_facelift', site_path='local/share/check_mk/web/htdocs/themes/facelift/images/mk-logo.png', excludes=[]), ] return expected
def expected_items() -> Dict[str, List[str]]: agents_items = [] if cmk_version.is_raw_edition(): agents_items += [ "download_agents_linux", "download_agents_windows", ] else: agents_items += [ "agents", ] agents_items += [ "download_agents", ] if not cmk_version.is_raw_edition(): agents_items.append("agent_registration") agents_items += [ "wato.py?group=vm_cloud_container&mode=rulesets", "wato.py?group=datasource_programs&mode=rulesets", "wato.py?group=agent&mode=rulesets", "wato.py?group=snmp&mode=rulesets", ] events_items = [ "notifications", "mkeventd_rule_packs", ] if not cmk_version.is_raw_edition(): events_items.append("alert_handlers") maintenance_items = ["backup"] if not cmk_version.is_raw_edition(): maintenance_items.append("license_usage") maintenance_items.append("mkps") maintenance_items += [ "diagnostics", "analyze_config", "background_jobs_overview", ] hosts_items = [ "folder", "wato.py?group=host_monconf&mode=rulesets", "tags", ] if not cmk_version.is_raw_edition(): hosts_items.append("dcd_connections") hosts_items += [ "host_groups", "host_attrs", "wato.py?group=inventory&mode=rulesets", ] users_items = [ "users", "contact_groups", "roles", "ldap_config", "user_attrs", ] if cmk_version.is_managed_edition(): users_items.insert(0, "customer_management") expected_items_dict = { "agents": agents_items, "events": events_items, "general": [ "rule_search", "globalvars", "read_only", "predefined_conditions", "timeperiods", "passwords", "sites", "auditlog", "icons", ], "hosts": hosts_items, "maintenance": maintenance_items, "services": [ "wato.py?group=monconf&mode=rulesets", "wato.py?group=checkparams&mode=rulesets", "wato.py?group=static&mode=rulesets", "wato.py?group=activechecks&mode=rulesets", "wato.py?group=custom_checks&mode=rulesets", "service_groups", "check_plugins", ], "bi": ["bi_packs"], "users": users_items, } if not cmk_version.is_raw_edition(): expected_items_dict.update({"custom": ["influxdb_connections"]}) return expected_items_dict
def test_registered_permissions(): expected_permissions = [ 'action.acknowledge', 'action.addcomment', 'action.clearmodattr', 'action.customnotification', 'action.downtimes', 'action.enablechecks', 'action.fakechecks', 'action.notifications', 'action.remove_all_downtimes', 'action.reschedule', 'action.star', 'action.delete_crash_report', 'background_jobs.delete_foreign_jobs', 'background_jobs.delete_jobs', 'background_jobs.manage_jobs', 'background_jobs.see_foreign_jobs', 'background_jobs.stop_foreign_jobs', 'background_jobs.stop_jobs', 'bi.see_all', 'dashboard.main', 'dashboard.simple_problems', 'dashboard.topology', 'general.acknowledge_werks', 'general.act', 'general.change_password', 'general.configure_sidebar', 'general.csv_export', 'general.delete_foreign_bookmark_list', 'general.delete_foreign_custom_snapin', 'general.delete_foreign_dashboards', 'general.delete_foreign_views', 'general.disable_notifications', 'general.edit_bookmark_list', 'general.edit_custom_snapin', 'general.edit_dashboards', 'general.edit_foreign_bookmark_list', 'general.edit_foreign_dashboards', 'general.edit_foreign_views', 'general.edit_foreign_custom_snapin', 'general.edit_notifications', 'general.edit_profile', 'general.edit_user_attributes', 'general.edit_views', 'general.force_bookmark_list', 'general.force_custom_snapin', 'general.force_dashboards', 'general.force_views', 'general.ignore_hard_limit', 'general.ignore_soft_limit', 'general.logout', 'general.notify', 'general.painter_options', 'general.publish_bookmark_list', 'general.publish_to_foreign_groups_bookmark_list', 'general.publish_custom_snapin', 'general.publish_to_foreign_groups_custom_snapin', 'general.publish_dashboards', 'general.publish_dashboards_to_foreign_groups', 'general.publish_views', 'general.publish_views_to_foreign_groups', 'general.see_all', 'general.see_availability', 'general.see_crash_reports', 'general.see_failed_notifications', 'general.see_failed_notifications_24h', 'general.see_sidebar', 'general.see_stales_in_tactical_overview', 'general.see_user_bookmark_list', 'general.see_user_custom_snapin', 'general.see_user_dashboards', 'general.see_user_views', 'general.use', 'general.view_option_columns', 'general.view_option_refresh', 'icons_and_actions.action_menu', 'icons_and_actions.aggregation_checks', 'icons_and_actions.aggregations', 'icons_and_actions.check_manpage', 'icons_and_actions.check_period', 'icons_and_actions.crashed_check', 'icons_and_actions.custom_action', 'icons_and_actions.download_agent_output', 'icons_and_actions.download_snmp_walk', 'icons_and_actions.icon_image', 'icons_and_actions.inventory', 'icons_and_actions.logwatch', 'icons_and_actions.mkeventd', 'icons_and_actions.notes', 'icons_and_actions.perfgraph', 'icons_and_actions.prediction', 'icons_and_actions.reschedule', 'icons_and_actions.rule_editor', 'icons_and_actions.stars', 'icons_and_actions.status_acknowledged', 'icons_and_actions.status_active_checks', 'icons_and_actions.status_comments', 'icons_and_actions.status_downtimes', 'icons_and_actions.status_flapping', 'icons_and_actions.status_notification_period', 'icons_and_actions.status_notifications_enabled', 'icons_and_actions.status_passive_checks', 'icons_and_actions.status_service_period', 'icons_and_actions.status_stale', 'icons_and_actions.wato', 'icons_and_actions.parent_child_topology', 'mkeventd.actions', 'mkeventd.activate', 'mkeventd.archive_events_of_hosts', 'mkeventd.changestate', 'mkeventd.config', 'mkeventd.delete', 'mkeventd.edit', 'mkeventd.see_in_tactical_overview', 'mkeventd.seeall', 'mkeventd.seeunrelated', 'mkeventd.switchmode', 'mkeventd.update', 'mkeventd.update_comment', 'mkeventd.update_contact', 'nagvis.*_*_*', 'nagvis.Map_delete', 'nagvis.Map_delete_*', 'nagvis.Map_edit', 'nagvis.Map_edit_*', 'nagvis.Map_view', 'nagvis.Map_view_*', 'nagvis.Rotation_view_*', 'notification_plugin.asciimail', 'notification_plugin.cisco_webex_teams', 'notification_plugin.jira_issues', 'notification_plugin.mail', 'notification_plugin.mkeventd', 'notification_plugin.opsgenie_issues', 'notification_plugin.pagerduty', 'notification_plugin.pushover', 'notification_plugin.servicenow', 'notification_plugin.slack', 'notification_plugin.sms', 'notification_plugin.spectrum', 'notification_plugin.victorops', 'sidesnap.about', 'sidesnap.admin', 'sidesnap.admin_mini', 'sidesnap.biaggr_groups', 'sidesnap.biaggr_groups_tree', 'sidesnap.bookmarks', 'sidesnap.custom_links', 'sidesnap.dashboards', 'sidesnap.hostgroups', 'sidesnap.hostmatrix', 'sidesnap.hosts', 'sidesnap.master_control', 'sidesnap.mkeventd_performance', 'sidesnap.nagios_legacy', 'sidesnap.nagvis_maps', 'sidesnap.performance', 'sidesnap.problem_hosts', 'sidesnap.search', 'sidesnap.servicegroups', 'sidesnap.sitestatus', 'sidesnap.speedometer', 'sidesnap.tactical_overview', 'sidesnap.tag_tree', 'sidesnap.time', 'sidesnap.views', 'sidesnap.wato_folders', 'sidesnap.wato_foldertree', 'sidesnap.wiki', 'view.aggr_all', 'view.aggr_all_api', 'view.aggr_group', 'view.aggr_host', 'view.aggr_hostgroup_boxed', 'view.aggr_hostnameaggrs', 'view.aggr_hostproblems', 'view.aggr_problems', 'view.aggr_service', 'view.aggr_single', 'view.aggr_single_api', 'view.aggr_singlehost', 'view.aggr_singlehosts', 'view.aggr_summary', 'view.alerthandlers', 'view.alertstats', 'view.allhosts', 'view.allhosts_mini', 'view.bi_map_hover_host', 'view.bi_map_hover_service', 'view.allservices', 'view.api_downtimes', 'view.comments', 'view.comments_of_host', 'view.comments_of_service', 'view.contactnotifications', 'view.crash_reports', 'view.downtime_history', 'view.downtimes', 'view.downtimes_of_host', 'view.downtimes_of_service', 'view.docker_containers', 'view.docker_nodes', 'view.vpshere_vms', 'view.vsphere_servers', 'view.ec_event', 'view.ec_event_mobile', 'view.ec_events', 'view.ec_events_mobile', 'view.ec_events_of_host', 'view.ec_events_of_monhost', 'view.ec_history_of_event', 'view.ec_history_of_host', 'view.ec_history_recent', 'view.ec_historyentry', 'view.events', 'view.events_dash', 'view.failed_notifications', 'view.host', 'view.host_crit', 'view.host_dt_hist', 'view.host_export', 'view.host_ok', 'view.host_pending', 'view.host_unknown', 'view.host_warn', 'view.hostevents', 'view.hostgroup', 'view.hostgroup_up', 'view.hostgroup_down', 'view.hostgroup_unreach', 'view.hostgroup_pend', 'view.hostgroupgrid', 'view.hostgroups', 'view.hostgroupservices', 'view.hostgroupservices_ok', 'view.hostgroupservices_warn', 'view.hostgroupservices_crit', 'view.hostgroupservices_unknwn', 'view.hostgroupservices_pend', 'view.hostnotifications', 'view.hostpnp', 'view.hostproblems', 'view.hostproblems_dash', 'view.hosts', 'view.hostsbygroup', 'view.hoststatus', 'view.hostsvcevents', 'view.hostsvcnotifications', 'view.hosttiles', 'view.inv_host', 'view.inv_host_history', 'view.inv_hosts_cpu', 'view.inv_hosts_ports', 'view.invbackplane_of_host', 'view.invbackplane_search', 'view.invchassis_of_host', 'view.invchassis_search', 'view.invcmksites_of_host', 'view.invcmksites_search', 'view.invcmkversions_of_host', 'view.invcmkversions_search', 'view.invcontainer_of_host', 'view.invcontainer_search', 'view.invdockercontainers_of_host', 'view.invdockercontainers_search', 'view.invdockerimages_of_host', 'view.invdockerimages_search', 'view.invfan_of_host', 'view.invfan_search', 'view.invibmmqchannels_of_host', 'view.invibmmqchannels_search', 'view.invibmmqmanagers_of_host', 'view.invibmmqmanagers_search', 'view.invibmmqqueues_of_host', 'view.invibmmqqueues_search', 'view.invinterface_of_host', 'view.invinterface_search', 'view.invkernelconfig_of_host', 'view.invkernelconfig_search', 'view.invmodule_of_host', 'view.invmodule_search', 'view.invoradataguardstats_of_host', 'view.invoradataguardstats_search', 'view.invorainstance_of_host', 'view.invorainstance_search', 'view.invorarecoveryarea_of_host', 'view.invorarecoveryarea_search', 'view.invorasga_of_host', 'view.invorasga_search', 'view.invorapga_of_host', 'view.invorapga_search', 'view.invoratablespace_of_host', 'view.invoratablespace_search', 'view.invorasystemparameter_of_host', 'view.invorasystemparameter_search', 'view.invother_of_host', 'view.invother_search', 'view.invpsu_of_host', 'view.invpsu_search', 'view.invsensor_of_host', 'view.invsensor_search', 'view.invstack_of_host', 'view.invstack_search', 'view.invswpac_of_host', 'view.invswpac_search', 'view.invtunnels_of_host', 'view.invtunnels_search', 'view.invunknown_of_host', 'view.invunknown_search', 'view.logfile', 'view.mobile_contactnotifications', 'view.mobile_events', 'view.mobile_host', 'view.mobile_hostproblems', 'view.mobile_hostproblems_unack', 'view.mobile_hoststatus', 'view.mobile_hostsvcevents', 'view.mobile_hostsvcnotifications', 'view.mobile_notifications', 'view.mobile_searchhost', 'view.mobile_searchsvc', 'view.mobile_service', 'view.mobile_svcevents', 'view.mobile_svcnotifications', 'view.mobile_svcproblems', 'view.mobile_svcproblems_unack', 'view.nagstamon_hosts', 'view.nagstamon_svc', 'view.notifications', 'view.pending_discovery', 'view.pendingsvc', 'view.perf_matrix', 'view.perf_matrix_search', 'view.problemsofhost', 'view.recentsvc', 'view.searchhost', 'view.searchpnp', 'view.searchsvc', 'view.service', 'view.service_check_durations', 'view.servicedesc', 'view.servicedescpnp', 'view.servicegroup', 'view.sitehosts', 'view.sitesvcs', 'view.sitesvcs_crit', 'view.sitesvcs_ok', 'view.sitesvcs_pend', 'view.sitesvcs_unknwn', 'view.sitesvcs_warn', 'view.stale_hosts', 'view.starred_hosts', 'view.starred_services', 'view.svc_dt_hist', 'view.svcbygroups', 'view.svcbyhgroups', 'view.svcevents', 'view.svcgroups', 'view.svcgroups_grid', 'view.svcnotifications', 'view.svcproblems', 'view.svcproblems_dash', 'view.topology_hover_host', 'view.topology_filters', 'view.uncheckedsvc', 'view.unmonitored_services', 'wato.activate', 'wato.activateforeign', 'wato.add_or_modify_executables', 'wato.all_folders', 'wato.analyze_config', 'wato.api_allowed', 'wato.auditlog', 'wato.automation', 'wato.backups', 'wato.bi_admin', 'wato.bi_rules', 'wato.clear_auditlog', 'wato.clone_hosts', 'wato.custom_attributes', 'wato.diag_host', 'wato.diagnostics', 'wato.download_agent_output', 'wato.download_agents', 'wato.edit', 'wato.edit_all_passwords', 'wato.edit_all_predefined_conditions', 'wato.edit_folders', 'wato.edit_hosts', 'wato.global', 'wato.groups', 'wato.hosts', 'wato.hosttags', 'wato.icons', 'wato.manage_folders', 'wato.manage_hosts', 'wato.move_hosts', 'wato.notifications', 'wato.parentscan', 'wato.passwords', 'wato.pattern_editor', 'wato.random_hosts', 'wato.rename_hosts', 'wato.rulesets', 'wato.see_all_folders', 'wato.seeall', 'wato.service_discovery_to_ignored', 'wato.service_discovery_to_monitored', 'wato.service_discovery_to_removed', 'wato.service_discovery_to_undecided', 'wato.services', 'wato.set_read_only', 'wato.sites', 'wato.snapshots', 'wato.timeperiods', 'wato.update_dns_cache', 'wato.use', 'wato.users', 'view.cmk_servers', 'view.cmk_sites', 'view.cmk_sites_of_host', 'dashboard.cmk_overview', 'dashboard.cmk_host', 'view.host_graphs', 'view.service_graphs', ] if not cmk_version.is_raw_edition(): expected_permissions += [ 'general.edit_reports', 'icons_and_actions.agent_deployment', 'icons_and_actions.status_shadow', 'report.bi_availability', 'report.default', 'report.host', 'report.instant', 'report.instant_availability', 'report.instant_graph_collection', 'report.instant_view', 'report.service_availability', 'report.host_performance_graphs', 'sidesnap.cmc_stats', 'sidesnap.reports', 'view.allhosts_deploy', 'wato.agent_deploy_custom_files', 'wato.agent_deployment', 'wato.agents', 'wato.alert_handlers', 'wato.bake_agents', 'wato.dcd_connections', 'wato.download_all_agents', 'wato.manage_mkps', 'wato.mkps', 'wato.sign_agents', 'general.delete_foreign_custom_graph', 'general.delete_foreign_forecast_graph', 'general.delete_foreign_graph_collection', 'general.delete_foreign_graph_tuning', 'general.delete_foreign_reports', 'general.delete_foreign_sla_configuration', 'general.delete_foreign_stored_report', 'general.delete_stored_report', 'general.edit_custom_graph', 'general.edit_forecast_graph', 'general.edit_foreign_forecast_graph', 'general.edit_foreign_custom_graph', 'general.edit_foreign_graph_collection', 'general.edit_foreign_graph_tuning', 'general.edit_foreign_reports', 'general.edit_foreign_sla_configuration', 'general.edit_graph_collection', 'general.edit_graph_tuning', 'general.edit_sla_configuration', 'general.force_custom_graph', 'general.publish_forecast_graph', 'general.force_graph_collection', 'general.force_graph_tuning', 'general.publish_graph_collection', 'general.publish_to_foreign_groups_graph_collection', 'general.publish_graph_tuning', 'general.publish_to_foreign_groups_graph_tuning', 'general.publish_reports', 'general.publish_reports_to_foreign_groups', 'general.publish_sla_configuration', 'general.publish_to_foreign_groups_sla_configuration', 'general.publish_stored_report', 'general.publish_to_foreign_groups_forecast_graph', 'general.see_user_custom_graph', 'general.see_user_forecast_graph', 'general.see_user_graph_collection', 'general.see_user_graph_tuning', 'general.see_user_reports', 'general.see_user_sla_configuration', 'general.see_user_stored_report', 'general.reporting', 'general.schedule_reports', 'general.schedule_reports_all', 'general.force_forecast_graph', 'general.force_reports', 'general.force_sla_configuration', 'general.instant_reports', 'general.publish_custom_graph', 'general.publish_to_foreign_groups_custom_graph', 'icons_and_actions.deployment_status', 'icons_and_actions.ntop_host_interface', 'icons_and_actions.ntop_service_interface', ] if cmk_version.is_managed_edition(): expected_permissions += [ "wato.customer_management", "view.customers", "view.customer_hosts", "view.customer_hosts_up", "view.customer_hosts_down", "view.customer_hosts_pend", "view.customer_hosts_unreach", "sidesnap.customers", ] assert sorted(expected_permissions) == sorted(permission_registry.keys()) for perm_class in permission_registry.values(): perm = perm_class() assert isinstance(perm.description, str) assert isinstance(perm.title, str) assert isinstance(perm.defaults, list)
def test_registered_modules(): expected_modules = [ "folder", "tags", "globalvars", "host_attrs", "wato.py?group=static&mode=rulesets", "check_plugins", "read_only", "predefined_conditions", "host_groups", "service_groups", "users", "user_attrs", "roles", "contact_groups", "notifications", "timeperiods", "mkeventd_rule_packs", "bi_packs", "sites", "backup", "passwords", "analyze_config", "auditlog", "icons", "background_jobs_overview", "ldap_config", "diagnostics", "download_agents", "rule_search", "wato.py?group=activechecks&mode=rulesets", "wato.py?group=agent&mode=rulesets", "wato.py?group=agents&mode=rulesets", "wato.py?group=checkparams&mode=rulesets", "wato.py?group=custom_checks&mode=rulesets", "wato.py?group=datasource_programs&mode=rulesets", "wato.py?group=inventory&mode=rulesets", "wato.py?group=monconf&mode=rulesets", "wato.py?group=host_monconf&mode=rulesets", "wato.py?group=snmp&mode=rulesets", "wato.py?group=vm_cloud_container&mode=rulesets", "wato.py?group=eventconsole&mode=rulesets", ] if cmk_version.is_raw_edition(): expected_modules += [ "download_agents_linux", "download_agents_windows", ] if not cmk_version.is_raw_edition(): expected_modules += [ "agent_registration", "agents", "alert_handlers", "dcd_connections", "influxdb_connections", "license_usage", "mkps", ] if cmk_version.is_managed_edition(): expected_modules += [ "customer_management", ] assert sorted( m().mode_or_url for m in main_module_registry.values()) == sorted(expected_modules)
def expected_items() -> Dict[str, List[str]]: agents_items = [] if cmk_version.is_raw_edition(): agents_items += [ 'download_agents_linux', 'download_agents_windows', ] else: agents_items += [ 'agents', ] agents_items += [ 'download_agents', 'wato.py?group=vm_cloud_container&mode=rulesets', 'wato.py?group=datasource_programs&mode=rulesets', 'wato.py?group=agent&mode=rulesets', 'wato.py?group=snmp&mode=rulesets', ] events_items = [ 'notifications', 'mkeventd_rule_packs', ] if not cmk_version.is_raw_edition(): events_items.append('alert_handlers') maintenance_items = ['backup'] if not cmk_version.is_raw_edition(): maintenance_items.append('license_usage') maintenance_items.append('mkps') maintenance_items += [ 'diagnostics', 'analyze_config', 'background_jobs_overview', ] hosts_items = [ 'folder', 'wato.py?group=host_monconf&mode=rulesets', 'tags', ] if not cmk_version.is_raw_edition(): hosts_items.append('dcd_connections') hosts_items += [ 'host_groups', 'host_attrs', 'wato.py?group=inventory&mode=rulesets', ] users_items = [ 'users', 'contact_groups', 'roles', 'ldap_config', 'user_attrs', ] if cmk_version.is_managed_edition(): users_items.insert(0, 'customer_management') return { 'agents': agents_items, 'events': events_items, 'general': [ 'rule_search', 'globalvars', 'read_only', 'predefined_conditions', 'timeperiods', 'passwords', 'sites', 'auditlog', 'icons', ], 'hosts': hosts_items, 'maintenance': maintenance_items, 'services': [ 'wato.py?group=monconf&mode=rulesets', 'wato.py?group=checkparams&mode=rulesets', 'wato.py?group=static&mode=rulesets', 'wato.py?group=activechecks&mode=rulesets', 'wato.py?group=custom_checks&mode=rulesets', 'service_groups', 'check_plugins', ], 'bi': ['bi_packs'], 'users': users_items, }
from cmk.utils.livestatus_helpers.queries import Query from cmk.utils.livestatus_helpers.tables import Hostgroups, Hosts, Servicegroups from cmk.utils.livestatus_helpers.types import Column, Table from cmk.gui import sites, watolib from cmk.gui.exceptions import MKUserError from cmk.gui.fields.base import BaseSchema, MultiNested, ValueTypedDictSchema from cmk.gui.fields.utils import attr_openapi_schema, collect_attributes, ObjectContext, ObjectType from cmk.gui.groups import GroupName, GroupType, load_group_information from cmk.gui.logged_in import user from cmk.gui.site_config import allsites from cmk.gui.watolib.passwords import contact_group_choices, password_exists from cmk.fields import base, DateTime if version.is_managed_edition(): import cmk.gui.cme.managed as managed # pylint: disable=no-name-in-module class PythonString(base.String): """Represent a Python value expression. Any native Python datastructures like tuple, dict, set, etc. can be used. Examples: >>> expr = PythonString() >>> expr.deserialize("{}") {} >>> expr.deserialize("{'a': (5.5, None)}")
def customer_field(**kw): if version.is_managed_edition(): return _CustomerField(**kw) return None
def _connect_multiple_sites(user: LoggedInUser) -> None: enabled_sites, disabled_sites = _get_enabled_and_disabled_sites(user) _set_initial_site_states(enabled_sites, disabled_sites) if is_managed_edition(): # Astroid 2.x bug prevents us from using NewType https://github.com/PyCQA/pylint/issues/2296 import cmk.gui.cme.managed as managed # pylint: disable=no-name-in-module g.live = managed.CMEMultiSiteConnection(enabled_sites, disabled_sites) else: g.live = MultiSiteConnection(enabled_sites, disabled_sites) # Fetch status of sites by querying the version of Nagios and livestatus # This may be cached by a proxy for up to the next configuration reload. g.live.set_prepend_site(True) for response in g.live.query( "GET status\n" "Cache: reload\n" "Columns: livestatus_version program_version program_start num_hosts num_services " "core_pid"): try: site_id, v1, v2, ps, num_hosts, num_services, pid = response except ValueError: e = MKLivestatusQueryError("Invalid response to status query: %s" % response) site_id = response[0] g.site_status[site_id].update({ "exception": e, "status_host_state": None, "state": _status_host_state_name(None), }) continue g.site_status[site_id].update({ "state": "online", "livestatus_version": v1, "program_version": v2, "program_start": ps, "num_hosts": num_hosts, "num_services": num_services, "core": v2.startswith("Check_MK") and "cmc" or "nagios", "core_pid": pid, }) g.live.set_prepend_site(False) # TODO(lm): Find a better way to make the Livestatus object trigger the update # once self.deadsites is updated. update_site_states_from_dead_sites()
def _get_expected_paths(user_id, is_pre_17_site, with_local): expected_paths = [ "etc", "var", "etc/check_mk", "etc/check_mk/conf.d", "etc/check_mk/mkeventd.d", "etc/check_mk/multisite.d", "etc/check_mk/conf.d/wato", "etc/check_mk/conf.d/wato/hosts.mk", "etc/check_mk/conf.d/wato/contacts.mk", "etc/check_mk/mkeventd.d/wato", "etc/check_mk/multisite.d/wato", "etc/check_mk/multisite.d/wato/global.mk", "var/check_mk", "var/check_mk/web", "etc/htpasswd", "etc/auth.serials", "etc/check_mk/multisite.d/wato/users.mk", "var/check_mk/web/%s" % user_id, "var/check_mk/web/%s/cached_profile.mk" % user_id, "var/check_mk/web/%s/enforce_pw_change.mk" % user_id, "var/check_mk/web/%s/last_pw_change.mk" % user_id, "var/check_mk/web/%s/num_failed_logins.mk" % user_id, "var/check_mk/web/%s/serial.mk" % user_id, ] if with_local: expected_paths += [ "local", "var/check_mk/packages", ] # The new sync directories create all needed files on the central site now if not is_pre_17_site: expected_paths += [ "etc/check_mk/apache.d", "etc/check_mk/apache.d/wato", "etc/check_mk/apache.d/wato/sitespecific.mk", "etc/check_mk/conf.d/distributed_wato.mk", "etc/check_mk/conf.d/wato/sitespecific.mk", "etc/check_mk/mkeventd.d/wato/sitespecific.mk", "etc/check_mk/multisite.d/wato/ca-certificates_sitespecific.mk", "etc/check_mk/multisite.d/wato/sitespecific.mk", "etc/check_mk/rrdcached.d", "etc/check_mk/rrdcached.d/wato", "etc/check_mk/rrdcached.d/wato/sitespecific.mk", "etc/omd", "etc/omd/sitespecific.mk", ] if is_enterprise_repo(): expected_paths += [ "etc/check_mk/dcd.d/wato/sitespecific.mk", "etc/check_mk/mknotifyd.d/wato/sitespecific.mk", ] if not cmk_version.is_raw_edition(): expected_paths += ["etc/check_mk/dcd.d/wato/distributed.mk"] # TODO: The second condition should not be needed. Seems to be a subtle difference between the # CME and CRE/CEE snapshot logic if not cmk_version.is_managed_edition(): expected_paths += [ "etc/check_mk/mkeventd.d/mkp", "etc/check_mk/mkeventd.d/mkp/rule_packs", ] # The paths are registered once the enterprise plugins are available, independent of the # cmk_version.edition_short() value. # TODO: The second condition should not be needed. Seems to be a subtle difference between the # CME and CRE/CEE snapshot logic if is_enterprise_repo() and (not is_pre_17_site or not cmk_version.is_managed_edition()): expected_paths += [ "etc/check_mk/dcd.d", "etc/check_mk/dcd.d/wato", "etc/check_mk/mknotifyd.d", "etc/check_mk/mknotifyd.d/wato", ] # TODO: Shouldn't we clean up these subtle differences? if cmk_version.is_managed_edition(): expected_paths += [ "etc/check_mk/conf.d/customer.mk", "etc/check_mk/conf.d/wato/groups.mk", "etc/check_mk/mkeventd.d/wato/rules.mk", "etc/check_mk/multisite.d/customer.mk", "etc/check_mk/multisite.d/wato/bi.mk", "etc/check_mk/multisite.d/wato/customers.mk", "etc/check_mk/multisite.d/wato/groups.mk", "etc/check_mk/multisite.d/wato/user_connections.mk", ] expected_paths.remove("etc/check_mk/conf.d/wato/hosts.mk") # TODO: The second condition should not be needed. Seems to be a subtle difference between the # CME and CRE/CEE snapshot logic if not cmk_version.is_raw_edition() and not cmk_version.is_managed_edition( ): expected_paths += [ "etc/check_mk/liveproxyd.d", "etc/check_mk/liveproxyd.d/wato", ] return expected_paths
def test_registered_modules(): expected_modules = [ 'folder', 'tags', 'globalvars', 'host_attrs', 'wato.py?mode=rulesets&group=static', 'check_plugins', 'read_only', 'predefined_conditions', 'host_groups', 'service_groups', 'users', 'user_attrs', 'roles', 'contact_groups', 'notifications', 'timeperiods', 'mkeventd_rule_packs', 'bi_packs', 'sites', 'backup', 'passwords', 'analyze_config', 'auditlog', 'icons', 'background_jobs_overview', 'ldap_config', 'diagnostics', 'download_agents', 'version.py', 'rule_search', 'wato.py?mode=rulesets&group=activechecks', 'wato.py?mode=rulesets&group=agent', 'wato.py?mode=rulesets&group=checkparams', 'wato.py?mode=rulesets&group=custom_checks', 'wato.py?mode=rulesets&group=custom_integrations', 'wato.py?mode=rulesets&group=datasource_programs', 'wato.py?mode=rulesets&group=inventory', 'wato.py?mode=rulesets&group=monconf', 'wato.py?mode=rulesets&group=host_monconf', 'wato.py?mode=rulesets&group=snmp', 'wato.py?mode=rulesets&group=vm_cloud_container', ] if cmk_version.is_raw_edition(): expected_modules += [ 'download_agents_linux', 'download_agents_windows', ] if not cmk_version.is_raw_edition(): expected_modules += [ 'agents', 'alert_handlers', 'mkps', 'license_usage', 'dcd_connections', ] if cmk_version.is_managed_edition(): expected_modules += [ "customer_management", ] module_names = [m.mode_or_url for m in main_menu.get_modules()] assert sorted(module_names) == sorted(expected_modules)
# -*- coding: utf-8 -*- # Copyright (C) 2020 tribe29 GmbH - License: GNU General Public License v2 # This file is part of Checkmk (https://checkmk.com). It is subject to the terms and # conditions defined in the file COPYING, which is part of this source code package. import json import random import string import pytest from cmk.utils import version from tests.unit.cmk.gui.conftest import WebTestAppForCMK managedtest = pytest.mark.skipif(not version.is_managed_edition(), reason="see #7213") @managedtest @pytest.mark.parametrize("group_type", ["host", "contact", "service"]) def test_openapi_groups(group_type, aut_user_auth_wsgi_app: WebTestAppForCMK): name = _random_string(10) alias = _random_string(10) group = {"name": name, "alias": alias, "customer": "provider"} base = "/NO_SITE/check_mk/api/1.0" resp = aut_user_auth_wsgi_app.call_method( "post", base + f"/domain-types/{group_type}_group_config/collections/all",
def action(self): if not html.check_transaction(): return "users" if self._user_id is None: # same as self._is_new_user self._user_id = UserID(allow_empty=False).from_html_vars("user_id") user_attrs = {} else: self._user_id = html.request.get_unicode_input_mandatory( "edit").strip() user_attrs = self._users[UserId(self._user_id)] # Full name user_attrs["alias"] = html.request.get_unicode_input_mandatory( "alias").strip() # Locking user_attrs["locked"] = html.get_checkbox("locked") increase_serial = False if (UserId(self._user_id) in self._users and self._users[UserId( self._user_id)]["locked"] != user_attrs["locked"] and user_attrs["locked"]): increase_serial = True # when user is being locked now, increase the auth serial # Authentication: Password or Secret auth_method = html.request.var("authmethod") if auth_method == "secret": secret = html.request.get_str_input_mandatory("_auth_secret", "").strip() user_attrs["automation_secret"] = secret user_attrs["password"] = hash_password(secret) increase_serial = True # password changed, reflect in auth serial else: password = html.request.get_str_input_mandatory( "_password_" + self._pw_suffix(), '').strip() password2 = html.request.get_str_input_mandatory( "_password2_" + self._pw_suffix(), '').strip() # We compare both passwords only, if the user has supplied # the repeation! We are so nice to our power users... # Note: this validation is done before the main-validiation later on # It doesn't make any sense to put this block into the main validation function if password2 and password != password2: raise MKUserError("_password2", _("The both passwords do not match.")) # Detect switch back from automation to password if "automation_secret" in user_attrs: del user_attrs["automation_secret"] if "password" in user_attrs: del user_attrs[ "password"] # which was the encrypted automation password! if password: user_attrs["password"] = hash_password(password) user_attrs["last_pw_change"] = int(time.time()) increase_serial = True # password changed, reflect in auth serial # PW change enforcement user_attrs["enforce_pw_change"] = html.get_checkbox( "enforce_pw_change") if user_attrs["enforce_pw_change"]: increase_serial = True # invalidate all existing user sessions, enforce relogon # Increase serial (if needed) if increase_serial: user_attrs["serial"] = user_attrs.get("serial", 0) + 1 # Email address user_attrs["email"] = EmailAddress().from_html_vars("email") idle_timeout = watolib.get_vs_user_idle_timeout().from_html_vars( "idle_timeout") user_attrs["idle_timeout"] = idle_timeout if idle_timeout is not None: user_attrs["idle_timeout"] = idle_timeout elif idle_timeout is None and "idle_timeout" in user_attrs: del user_attrs["idle_timeout"] # Pager user_attrs["pager"] = html.request.get_str_input_mandatory( "pager", '').strip() if cmk_version.is_managed_edition(): customer = self._vs_customer.from_html_vars("customer") self._vs_customer.validate_value(customer, "customer") if customer != managed.default_customer_id(): user_attrs["customer"] = customer elif "customer" in user_attrs: del user_attrs["customer"] vs_sites = self._vs_sites() authorized_sites = vs_sites.from_html_vars("authorized_sites") vs_sites.validate_value(authorized_sites, "authorized_sites") if authorized_sites is not None: user_attrs["authorized_sites"] = authorized_sites elif "authorized_sites" in user_attrs: del user_attrs["authorized_sites"] # Roles user_attrs["roles"] = [ role for role in self._roles.keys() if html.get_checkbox("role_" + role) ] # Language configuration set_lang = html.get_checkbox("_set_lang") language = html.request.var("language") if set_lang: if language == "": language = None user_attrs["language"] = language elif not set_lang and "language" in user_attrs: del user_attrs["language"] # Contact groups cgs = [] for c in self._contact_groups: if html.get_checkbox("cg_" + c): cgs.append(c) user_attrs["contactgroups"] = cgs # Notification settings are only active if we do *not* have # rule based notifications! if not self._rbn_enabled(): # Notifications user_attrs["notifications_enabled"] = html.get_checkbox( "notifications_enabled") ntp = html.request.var("notification_period") if ntp not in self._timeperiods: ntp = "24X7" user_attrs["notification_period"] = ntp for what, opts in [("host", "durfs"), ("service", "wucrfs")]: user_attrs[what + "_notification_options"] = "".join([ opt for opt in opts if html.get_checkbox(what + "_" + opt) ]) value = watolib.get_vs_flexible_notifications().from_html_vars( "notification_method") user_attrs["notification_method"] = value else: user_attrs["fallback_contact"] = html.get_checkbox( "fallback_contact") # Custom user attributes for name, attr in userdb.get_user_attributes(): value = attr.valuespec().from_html_vars('ua_' + name) user_attrs[name] = value # Generate user "object" to update user_object = { self._user_id: { "attributes": user_attrs, "is_new_user": self._is_new_user } } # The following call validates and updated the users edit_users(user_object) return "users"
def _expected_replication_paths(): expected = [ ReplicationPath("dir", "check_mk", "etc/check_mk/conf.d/wato/", []), ReplicationPath("dir", "multisite", "etc/check_mk/multisite.d/wato/", []), ReplicationPath("file", "htpasswd", "etc/htpasswd", []), ReplicationPath("file", "auth.secret", "etc/auth.secret", []), ReplicationPath("file", "password_store.secret", "etc/password_store.secret", []), ReplicationPath("file", "auth.serials", "etc/auth.serials", []), ReplicationPath("file", "stored_passwords", "var/check_mk/stored_passwords", []), ReplicationPath("dir", "usersettings", "var/check_mk/web", ["report-thumbnails", "session_info.mk"]), ReplicationPath("dir", "mkps", "var/check_mk/packages", []), ReplicationPath("dir", "local", "local", []), ] if not cmk_version.is_raw_edition(): expected += [ ReplicationPath("dir", "liveproxyd", "etc/check_mk/liveproxyd.d/wato/", []), ] if testlib.is_enterprise_repo(): expected += [ ReplicationPath("dir", "dcd", "etc/check_mk/dcd.d/wato/", []), ReplicationPath("dir", "mknotify", "etc/check_mk/mknotifyd.d/wato", []), ] expected += [ ReplicationPath("dir", "mkeventd", "etc/check_mk/mkeventd.d/wato", []), ReplicationPath("dir", "mkeventd_mkp", "etc/check_mk/mkeventd.d/mkp/rule_packs", []), ReplicationPath("file", "diskspace", "etc/diskspace.conf", []), ] if cmk_version.is_managed_edition(): expected += [ ReplicationPath( ty="file", ident="customer_check_mk", site_path="etc/check_mk/conf.d/customer.mk", excludes=[], ), ReplicationPath( ty="file", ident="customer_gui_design", site_path="etc/check_mk/multisite.d/zzz_customer_gui_design.mk", excludes=[], ), ReplicationPath( ty="file", ident="customer_multisite", site_path="etc/check_mk/multisite.d/customer.mk", excludes=[], ), ReplicationPath( ty="file", ident="gui_logo", site_path= "local/share/check_mk/web/htdocs/themes/classic/images/sidebar_top.png", excludes=[], ), ReplicationPath( ty="file", ident="gui_logo_dark", site_path= "local/share/check_mk/web/htdocs/themes/modern-dark/images/mk-logo.png", excludes=[], ), ReplicationPath( ty="file", ident="gui_logo_facelift", site_path= "local/share/check_mk/web/htdocs/themes/facelift/images/mk-logo.png", excludes=[], ), ] return expected
import contextlib import json import http.client from typing import Any, Dict, Literal, Sequence, List, Optional, Type, Union, Tuple from cmk.gui.http import Response from cmk.gui.groups import load_group_information, GroupSpecs, GroupSpec from cmk.gui.plugins.openapi.restful_objects import constructors from cmk.gui.plugins.openapi.utils import ProblemException from cmk.gui.watolib import CREFolder from cmk.gui.watolib.groups import edit_group, GroupType from cmk.utils import version from cmk.utils.version import is_managed_edition if is_managed_edition(): import cmk.gui.cme.managed as managed # pylint: disable=no-name-in-module GroupName = Literal[ 'host_group_config', 'contact_group_config', 'service_group_config', 'agent' ] # yapf: disable def complement_customer(details): if not is_managed_edition(): return details
NEGATE, wato_root_dir, multisite_dir, rename_host_in_list, convert_cgroups_from_tuple, host_attribute_matches, default_site, format_config_value, liveproxyd_config_dir, mk_repr, mk_eval, has_agent_bakery, site_neutral_path, ) from cmk.gui.watolib.wato_background_job import WatoBackgroundJob if cmk_version.is_managed_edition(): import cmk.gui.cme.managed as managed # pylint: disable=no-name-in-module from cmk.gui.plugins.watolib.utils import ( ABCConfigDomain, config_domain_registry, config_variable_registry, wato_fileheader, SampleConfigGenerator, sample_config_generator_registry, ) import cmk.gui.plugins.watolib if not cmk_version.is_raw_edition(): import cmk.gui.cee.plugins.watolib # pylint: disable=no-name-in-module
def _show_user_list(self): visible_custom_attrs = [(name, attr) for name, attr in userdb.get_user_attributes() if attr.show_in_table()] users = userdb.load_users() entries = users.items() html.begin_form("bulk_delete_form", method="POST") roles = userdb.load_roles() timeperiods = watolib.timeperiods.load_timeperiods() contact_groups = load_contact_group_information() with table_element("users", None, empty_text=_("No users are defined yet.")) as table: online_threshold = time.time() - config.user_online_maxage for uid, user in sorted( entries, key=lambda x: x[1].get("alias", x[0]).lower()): table.row() # Checkboxes table.cell(html.render_input( "_toggle_group", type_="button", class_="checkgroup", onclick="cmk.selection.toggle_all_rows();", value='X'), sortable=False, css="checkbox") if uid != config.user.id: html.checkbox( "_c_user_%s" % six.ensure_str(base64.b64encode(uid.encode("utf-8")))) user_connection_id = cleanup_connection_id( user.get('connector')) connection = get_connection(user_connection_id) # Buttons table.cell(_("Actions"), css="buttons") if connection: # only show edit buttons when the connector is available and enabled edit_url = watolib.folder_preserving_link([("mode", "edit_user"), ("edit", uid)]) html.icon_button(edit_url, _("Properties"), "edit") clone_url = watolib.folder_preserving_link([ ("mode", "edit_user"), ("clone", uid) ]) html.icon_button(clone_url, _("Create a copy of this user"), "clone") delete_url = make_action_link([("mode", "users"), ("_delete", uid)]) html.icon_button(delete_url, _("Delete"), "delete") notifications_url = watolib.folder_preserving_link([ ("mode", "user_notifications"), ("user", uid) ]) if watolib.load_configuration_settings().get( "enable_rulebased_notifications"): html.icon_button( notifications_url, _("Custom notification table of this user"), "notifications") # ID table.cell(_("ID"), uid) # Online/Offline if config.save_user_access_times: last_seen = user.get('last_seen', 0) if last_seen >= online_threshold: title = _('Online') img_txt = 'online' elif last_seen != 0: title = _('Offline') img_txt = 'offline' elif last_seen == 0: title = _('Never logged in') img_txt = 'inactive' title += ' (%s %s)' % (render.date(last_seen), render.time_of_day(last_seen)) table.cell(_("Act.")) html.icon(title, img_txt) table.cell(_("Last seen")) if last_seen != 0: html.write_text("%s %s" % (render.date(last_seen), render.time_of_day(last_seen))) else: html.write_text(_("Never logged in")) if cmk_version.is_managed_edition(): table.cell(_("Customer"), managed.get_customer_name(user)) # Connection if connection: table.cell( _("Connection"), '%s (%s)' % (connection.short_title(), user_connection_id)) locked_attributes = userdb.locked_attributes( user_connection_id) else: table.cell( _("Connection"), "%s (%s) (%s)" % (_("UNKNOWN"), user_connection_id, _("disabled")), css="error") locked_attributes = [] # Authentication if "automation_secret" in user: auth_method = _("Automation") elif user.get("password") or 'password' in locked_attributes: auth_method = _("Password") else: auth_method = "<i>%s</i>" % _("none") table.cell(_("Authentication"), auth_method) table.cell(_("State")) if user.get("locked", False): html.icon(_('The login is currently locked'), 'user_locked') if "disable_notifications" in user and isinstance( user["disable_notifications"], bool): disable_notifications_opts = { "disable": user["disable_notifications"] } else: disable_notifications_opts = user.get( "disable_notifications", {}) if disable_notifications_opts.get("disable", False): html.icon(_('Notifications are disabled'), 'notif_disabled') # Full name / Alias table.text_cell(_("Alias"), user.get("alias", "")) # Email table.text_cell(_("Email"), user.get("email", "")) # Roles table.cell(_("Roles")) if user.get("roles", []): role_links = [(watolib.folder_preserving_link([ ("mode", "edit_role"), ("edit", role) ]), roles[role].get("alias")) for role in user["roles"]] html.write_html( HTML(", ").join( html.render_a(alias, href=link) for (link, alias) in role_links)) # contact groups table.cell(_("Contact groups")) cgs = user.get("contactgroups", []) if cgs: cg_aliases = [ contact_groups[c]['alias'] if c in contact_groups else c for c in cgs ] cg_urls = [ watolib.folder_preserving_link([("mode", "edit_contact_group"), ("edit", c)]) for c in cgs ] html.write_html( HTML(", ").join( html.render_a(content, href=url) for (content, url) in zip(cg_aliases, cg_urls))) else: html.i(_("none")) #table.cell(_("Sites")) #html.write(vs_authorized_sites().value_to_text(user.get("authorized_sites", # vs_authorized_sites().default_value()))) # notifications if not watolib.load_configuration_settings().get( "enable_rulebased_notifications"): table.cell(_("Notifications")) if not cgs: html.i(_("not a contact")) elif not user.get("notifications_enabled", True): html.write_text(_("disabled")) elif user.get("host_notification_options", "") == "" and \ user.get("service_notification_options", "") == "": html.write_text(_("all events disabled")) else: tp = user.get("notification_period", "24X7") if tp not in timeperiods: tp = tp + _(" (invalid)") elif tp not in watolib.timeperiods.builtin_timeperiods( ): url = watolib.folder_preserving_link([ ("mode", "edit_timeperiod"), ("edit", tp) ]) tp = html.render_a(timeperiod_spec_alias( timeperiods[tp], tp), href=url) else: tp = timeperiod_spec_alias(timeperiods[tp], tp) html.write(tp) # the visible custom attributes for name, attr in visible_custom_attrs: vs = attr.valuespec() table.cell(escaping.escape_attribute(_u(vs.title()))) html.write( vs.value_to_text(user.get(name, vs.default_value()))) html.button("_bulk_delete_users", _("Bulk Delete"), "submit", style="margin-top:10px") html.hidden_fields() html.end_form() if not load_contact_group_information(): url = "wato.py?mode=contact_groups" html.open_div(class_="info") html.write( _("Note: you haven't defined any contact groups yet. If you <a href='%s'>" "create some contact groups</a> you can assign users to them und thus " "make them monitoring contacts. Only monitoring contacts can receive " "notifications.") % url) html.write( " you can assign users to them und thus " "make them monitoring contacts. Only monitoring contacts can receive " "notifications.") html.close_div()