def edit_users(changed_users): all_users = userdb.load_users(lock=True) new_users_info = [] modified_users_info = [] for user_id, settings in changed_users.items(): user_attrs = settings.get("attributes") is_new_user = settings.get("is_new_user", True) _validate_user_attributes(all_users, user_id, user_attrs, is_new_user=is_new_user) if is_new_user: new_users_info.append(user_id) else: modified_users_info.append(user_id) if is_new_user: add_internal_attributes(user_attrs) old_object = make_user_audit_log_object(all_users.get(user_id, {})) log_audit(action="edit-user", message=(_("Created new user: %s") % user_id if is_new_user else _("Modified user: %s") % user_id), diff_text=make_diff_text(old_object, make_user_audit_log_object(user_attrs)), object_ref=make_user_object_ref(user_id)) all_users[user_id] = user_attrs if new_users_info: add_change("edit-users", _("Created new users: %s") % ", ".join(new_users_info)) if modified_users_info: add_change("edit-users", _("Modified users: %s") % ", ".join(modified_users_info)) userdb.save_users(all_users)
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 _delete_aux_tag(self) -> ActionResult: del_id = request.get_item_input( "_del_aux", dict(self._tag_config.aux_tag_list.get_choices()))[1] # Make sure that this aux tag is not begin used by any tag group for group in self._tag_config.tag_groups: for grouped_tag in group.tags: if del_id in grouped_tag.aux_tag_ids: raise MKUserError( None, _("You cannot delete this auxiliary tag. " "It is being used in the tag group <b>%s</b>.") % group.title, ) message = _rename_tags_after_confirmation( self.breadcrumb(), OperationRemoveAuxTag(del_id)) if message is False: return FinalizeRequest(code=200) if message: self._tag_config.aux_tag_list.remove(del_id) try: self._tag_config.validate_config() except MKGeneralException as e: raise MKUserError(None, "%s" % e) self._save_tags_and_update_hosts( self._tag_config.get_dict_format()) _changes.add_change( "edit-tags", _("Removed auxiliary tag %s (%s)") % (message, del_id)) if isinstance(message, str): flash(message) return redirect(mode_url("tags"))
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 _synchronize_profiles_to_sites(logger, profiles_to_synchronize): if not profiles_to_synchronize: return remote_sites = [(site_id, config.site(site_id)) for site_id in config.get_login_slave_sites()] logger.info('Credentials changed for %s. Trying to sync to %d sites' % (", ".join(profiles_to_synchronize.keys()), len(remote_sites))) states = sites.states() pool = ThreadPool() jobs = [] for site_id, site in remote_sites: jobs.append( pool.apply_async(_sychronize_profile_worker, (states, site_id, site, profiles_to_synchronize))) results = [] start_time = time.time() while time.time() - start_time < 30: for job in jobs[:]: try: results.append(job.get(timeout=0.5)) jobs.remove(job) except mp_TimeoutError: pass if not jobs: break contacted_sites = {x[0] for x in remote_sites} working_sites = {result.site_id for result in results} for site_id in contacted_sites - working_sites: results.append( SynchronizationResult( site_id, error_text=_("No response from update thread"), failed=True)) for result in results: if result.error_text: logger.info(' FAILED [%s]: %s' % (result.site_id, result.error_text)) if config.wato_enabled: add_change("edit-users", _('Password changed (sync failed: %s)') % result.error_text, add_user=False, sites=[result.site_id], need_restart=False) pool.terminate() pool.join() num_failed = sum([1 for result in results if result.failed]) num_disabled = sum([1 for result in results if result.disabled]) num_succeeded = sum([1 for result in results if result.succeeded]) logger.info(' Disabled: %d, Succeeded: %d, Failed: %d' % (num_disabled, num_succeeded, num_failed))
def insert_rule_after(self, rule, after): index = self._rules[rule.folder.path()].index(after) + 1 self._rules[rule.folder.path()].insert(index, rule) add_change("clone-ruleset", _("Cloned rule in ruleset '%s'") % self.title(), sites=rule.folder.all_site_ids()) self._on_change()
def _delete_tag_group(self) -> ActionResult: del_id = request.get_item_input( "_delete", dict(self._tag_config.get_tag_group_choices()))[1] if not request.has_var( "_repair") and self._is_cleaning_up_user_tag_group_to_builtin( del_id): message: Union[bool, str] = ( _('Transformed the user tag group "%s" to builtin.') % del_id) else: message = _rename_tags_after_confirmation( self.breadcrumb(), OperationRemoveTagGroup(del_id)) if message is False: return FinalizeRequest(code=200) if message: self._tag_config.remove_tag_group(del_id) try: self._tag_config.validate_config() except MKGeneralException as e: raise MKUserError(None, "%s" % e) self._save_tags_and_update_hosts( self._tag_config.get_dict_format()) _changes.add_change( "edit-tags", _("Removed tag group %s (%s)") % (message, del_id)) if isinstance(message, str): flash(message) return redirect(mode_url("tags"))
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 edit_users(changed_users): all_users = userdb.load_users(lock=True) new_users_info = [] modified_users_info = [] for user_id, settings in changed_users.items(): user_attrs = settings.get("attributes") is_new_user = settings.get("is_new_user", True) _validate_user_attributes(all_users, user_id, user_attrs, is_new_user=is_new_user) if is_new_user: new_users_info.append(user_id) else: modified_users_info.append(user_id) all_users[user_id] = user_attrs if new_users_info: add_change("edit-users", _("Created new user: %s") % ", ".join(new_users_info)) if modified_users_info: add_change("edit-users", _("Modified user: %s") % ", ".join(modified_users_info)) userdb.save_users(all_users)
def rename_host_in_folder_rules(folder): rulesets = watolib.FolderRulesets(folder) rulesets.load() changed_folder_rulesets = [] for varname, ruleset in rulesets.get_rulesets().items(): for _rule_folder, _rulenr, rule in ruleset.get_rules(): orig_rule = rule.clone(preserve_id=True) if rule.replace_explicit_host_condition(oldname, newname): changed_folder_rulesets.append(varname) log_audit( "edit-rule", _('Renamed host condition from "%s" to "%s"') % (oldname, newname), diff_text=make_diff_text(orig_rule.to_log(), rule.to_log()), object_ref=rule.object_ref(), ) if changed_folder_rulesets: add_change( "edit-ruleset", _("Renamed host in %d rulesets of folder %s") % (len(changed_folder_rulesets), folder.title()), object_ref=folder.object_ref(), sites=folder.all_site_ids(), ) rulesets.save() changed_rulesets.extend(changed_folder_rulesets) for subfolder in folder.subfolders(): rename_host_in_folder_rules(subfolder)
def _add_profile_replication_change(site_id: SiteId, result: Union[bool, str]) -> None: """Add pending change entry to make sync possible later for admins""" add_change("edit-users", _('Profile changed (sync failed: %s)') % result, sites=[site_id], need_restart=False)
def delete_users(users_to_delete): user.need_permission("wato.users") user.need_permission("wato.edit") if user.id in users_to_delete: raise MKUserError(None, _("You cannot delete your own account!")) all_users = userdb.load_users(lock=True) deleted_users = [] for entry in users_to_delete: if entry in all_users: # Silently ignore not existing users deleted_users.append(entry) del all_users[entry] else: raise MKUserError(None, _("Unknown user: %s") % entry) if deleted_users: for user_id in deleted_users: log_audit( "edit-user", _("Deleted user: %s") % user_id, object_ref=make_user_object_ref(user_id), ) add_change("edit-users", _("Deleted user: %s") % ", ".join(deleted_users)) userdb.save_users(all_users, datetime.now())
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 action(self) -> ActionResult: if not transactions.check_transaction(): return redirect(mode_url("tags")) vs = self._valuespec() tag_group_spec = vs.from_html_vars("tag_group") vs.validate_value(tag_group_spec, "tag_group") # Create new object with existing host tags changed_hosttags_config = cmk.utils.tags.TagConfig.from_config( self._tag_config_file.load_for_modification()) changed_tag_group = cmk.utils.tags.TagGroup.from_config(tag_group_spec) self._tag_group = changed_tag_group if self._new: # Inserts and verifies changed tag group changed_hosttags_config.insert_tag_group(changed_tag_group) try: changed_hosttags_config.validate_config() except MKGeneralException as e: raise MKUserError(None, "%s" % e) self._save_tags_and_update_hosts( changed_hosttags_config.get_dict_format()) _changes.add_change( "edit-hosttags", _("Created new host tag group '%s'") % changed_tag_group.id) flash( _("Created new host tag group '%s'") % changed_tag_group.title) return redirect(mode_url("tags")) # Updates and verifies changed tag group changed_hosttags_config.update_tag_group(changed_tag_group) try: changed_hosttags_config.validate_config() except MKGeneralException as e: raise MKUserError(None, "%s" % e) remove_tag_ids, replace_tag_ids = identify_modified_tags( changed_tag_group, self._untainted_tag_group) tg_id = self._tag_group.id if tg_id is None: raise Exception("tag group ID not set") operation = OperationReplaceGroupedTags(tg_id, remove_tag_ids, replace_tag_ids) # Now check, if any folders, hosts or rules are affected message = _rename_tags_after_confirmation(self.breadcrumb(), operation) if message is False: return FinalizeRequest(code=200) self._save_tags_and_update_hosts( changed_hosttags_config.get_dict_format()) _changes.add_change( "edit-hosttags", _("Edited host tag group %s (%s)") % (message, self._id)) if isinstance(message, str): flash(message) return redirect(mode_url("tags"))
def move_rule_to_bottom(self, rule): rules = self._rules[rule.folder.path()] index = rules.index(rule) rules.remove(rule) rules.append(rule) add_change("edit-ruleset", _("Moved rule #%d to bottom in ruleset \"%s\"") % (index, self.title()), sites=rule.folder.all_site_ids())
def move_rule_down(self, rule): rules = self._rules[rule.folder.path()] index = rules.index(rule) del rules[index] rules[index + 1:index + 1] = [rule] add_change("edit-ruleset", _("Moved rule #%d down in ruleset \"%s\"") % (index, self.title()), sites=rule.folder.all_site_ids())
def move_rule_to(self, rule, index): rules = self._rules[rule.folder.path()] old_index = rules.index(rule) rules.remove(rule) rules.insert(index, rule) add_change("edit-ruleset", _("Moved rule #%d to #%d in ruleset \"%s\"") % (old_index, index, self.title()), sites=rule.folder.all_site_ids())
def _add_group_change(group, action_name, text): group_sites = None if cmk.is_managed_edition() and not managed.is_global( managed.get_customer_id(group)): group_sites = managed.get_sites_of_customer( managed.get_customer_id(group)) add_change(action_name, text, sites=group_sites)
def move_rule_to(self, rule, index): rules = self._rules[rule.folder.path()] old_index = rules.index(rule) rules.remove(rule) rules.insert(index, rule) add_change("edit-ruleset", _("Moved rule %s from position #%d to #%d in ruleset \"%s\" in folder \"%s\"") % (rule.id, old_index, index, self.title(), rule.folder.alias_path()), sites=rule.folder.all_site_ids(), object_ref=self.object_ref())
def _add_group_change(group: GroupSpec, action_name: str, text: str) -> None: group_sites = None if cmk_version.is_managed_edition(): cid = managed.get_customer_id(group) if not managed.is_global(cid): if cid is None: # conditional caused by bad typing raise Exception("cannot happen: no customer ID") group_sites = list(managed.get_sites_of_customer(cid).keys()) add_change(action_name, text, sites=group_sites)
def action(self) -> ActionResult: if request.var("_action") != "discard": return None if not transactions.check_transaction(): return None if not self._may_discard_changes(): return None if not self.has_changes(): return None # Now remove all currently pending changes by simply restoring the last automatically # taken snapshot. Then activate the configuration. This should revert all pending changes. file_to_restore = self._get_last_wato_snapshot_file() if not file_to_restore: raise MKUserError(None, _("There is no WATO snapshot to be restored.")) msg = _("Discarded pending changes (Restored %s)") % file_to_restore # All sites and domains can be affected by a restore: Better restart everything. _changes.add_change( "changes-discarded", msg, domains=ABCConfigDomain.enabled_domains(), need_restart=True, ) self._extract_snapshot(file_to_restore) activate_changes.execute_activate_changes([ d.get_domain_request([]) for d in ABCConfigDomain.enabled_domains() ]) for site_id in activation_sites(): self.confirm_site_changes(site_id) build_index_background() make_header( html, self.title(), breadcrumb=self.breadcrumb(), show_body_start=display_options.enabled(display_options.H), show_top_heading=display_options.enabled(display_options.T), ) html.open_div(class_="wato") html.show_message(_("Successfully discarded all pending changes.")) html.javascript("hide_changes_buttons();") html.footer() return FinalizeRequest(code=200)
def clone_rule(self, orig_rule, rule): if rule.folder == orig_rule.folder: self.insert_rule_after(rule, orig_rule) else: self.append_rule(rule.folder, rule) add_change("new-rule", _("Cloned rule from rule %s in ruleset \"%s\" in folder \"%s\"") % (orig_rule.id, self.title(), rule.folder.alias_path()), sites=rule.folder.all_site_ids(), diff_text=make_diff_text({}, rule.to_web_api()), object_ref=rule.object_ref())
def edit_rule(self, orig_rule, rule): folder_rules = self._rules[orig_rule.folder.path()] index = folder_rules.index(orig_rule) folder_rules[index] = rule add_change("edit-rule", _("Changed properties of rule #%d in ruleset \"%s\" in folder \"%s\"") % (index, self.title(), rule.folder.alias_path()), sites=rule.folder.all_site_ids(), diff_text=make_diff_text(orig_rule.to_web_api(), rule.to_web_api()), object_ref=rule.object_ref()) self._on_change()
def delete_rule(self, rule, create_change=True): folder_rules = self._rules[rule.folder.path()] index = folder_rules.index(rule) folder_rules.remove(rule) del self._rules_by_id[rule.id] if create_change: add_change("edit-rule", _("Deleted rule #%d in ruleset \"%s\" in folder \"%s\"") % (index, self.title(), rule.folder.alias_path()), sites=rule.folder.all_site_ids(), object_ref=rule.object_ref()) self._on_change()
def clone_rule(self, orig_rule: Rule, rule: Rule) -> None: if rule.folder == orig_rule.folder: self.insert_rule_after(rule, orig_rule) else: self.append_rule(rule.folder, rule) add_change( "new-rule", _('Cloned rule from rule %s in ruleset "%s" in folder "%s"') % (orig_rule.id, self.title(), rule.folder.alias_path()), sites=rule.folder.all_site_ids(), diff_text=make_diff_text({}, rule.to_log()), object_ref=rule.object_ref(), )
def _add_change( self, *, action: str, text: str, affected_sites: Optional[List[SiteId]], ) -> None: """Add a WATO change entry for this object type modifications""" _changes.add_change( "%s-%s" % (action, self._mode_type.type_name()), text, domains=self._mode_type.affected_config_domains(), sites=affected_sites, )
def _add_change(ident, new_password): if new_password: add_change( "add-password", f"Added the password {ident}", domains=[ConfigDomainCore], sites=None, ) else: # update or delete add_change( "edit-password", f"Edited the password '{ident}'", domains=[ConfigDomainCore], sites=None, )
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 _move_tag_group(self) -> ActionResult: # pylint: disable=useless-return move_nr = request.get_integer_input_mandatory("_move") move_to = request.get_integer_input_mandatory("_index") moved = self._tag_config.tag_groups.pop(move_nr) self._tag_config.tag_groups.insert(move_to, moved) try: self._tag_config.validate_config() except MKGeneralException as e: raise MKUserError(None, "%s" % e) self._tag_config_file.save(self._tag_config.get_dict_format()) self._load_effective_config() _changes.add_change("edit-tags", _("Changed order of tag groups")) return None
def edit_rule(self, orig_rule: Rule, rule: Rule) -> None: folder_rules = self._rules[orig_rule.folder.path()] index = folder_rules.index(orig_rule) folder_rules[index] = rule add_change( "edit-rule", _('Changed properties of rule #%d in ruleset "%s" in folder "%s"') % (index, self.title(), rule.folder.alias_path()), sites=rule.folder.all_site_ids(), diff_text=make_diff_text(orig_rule.to_log(), rule.to_log()), object_ref=rule.object_ref(), ) self._on_change()