def _get(self, request): hosttags_config = cmk.utils.tags.TagConfig() hosttags_config.parse_config(TagConfigFile().load_for_reading()) hosttags_dict = hosttags_config.get_dict_format() # The configuration hash is computed for the configurable hosttags add_configuration_hash(hosttags_dict, hosttags_dict) # Looks strange, but is OK hosttags_dict["builtin"] = self._get_builtin_tags_configuration() return hosttags_dict
def _set(self, request): tag_config_file = TagConfigFile() hosttags_config = cmk.utils.tags.TagConfig() hosttags_config.parse_config(tag_config_file.load_for_modification()) hosttags_dict = hosttags_config.get_dict_format() if "configuration_hash" in request: validate_config_hash(request["configuration_hash"], hosttags_dict) del request["configuration_hash"] # Check for conflicts with existing configuration # Tags may be either specified grouped in a host/folder configuration, e.g agent/cmk-agent, # or specified as the plain id in rules. We need to check both variants.. used_tags = self._get_used_grouped_tags() used_tags.update(self._get_used_rule_tags()) changed_hosttags_config = cmk.utils.tags.TagConfig() changed_hosttags_config.parse_config(request) changed_hosttags_config.validate_config() new_tags = changed_hosttags_config.get_tag_ids() new_tags.update( changed_hosttags_config.get_tag_ids_with_group_prefix()) # Remove the builtin hoststags from the list of used_tags builtin_config = cmk.utils.tags.BuiltinTagConfig() used_tags.discard(builtin_config.get_tag_ids_with_group_prefix()) missing_tags = used_tags - new_tags if missing_tags: raise MKUserError( None, _("Unable to apply new hosttag configuration. The following tags " "are still in use, but not mentioned in the updated " "configuration: %s") % ", ".join(missing_tags)) tag_config_file.save(changed_hosttags_config.get_dict_format()) watolib.add_change("edit-hosttags", _("Updated host tags through Web-API"))
class ABCTagMode(WatoMode): __metaclass__ = abc.ABCMeta def __init__(self): super(ABCTagMode, self).__init__() self._tag_config_file = TagConfigFile() self._load_effective_config() def _save_tags_and_update_hosts(self, tag_config): self._tag_config_file.save(tag_config) config.load_config() watolib.Folder.invalidate_caches() watolib.Folder.root_folder().rewrite_hosts_files() def _load_effective_config(self): self._builtin_config = cmk.utils.tags.BuiltinTagConfig() self._tag_config = cmk.utils.tags.TagConfig() self._tag_config.parse_config(self._tag_config_file.load_for_reading()) self._effective_config = cmk.utils.tags.TagConfig() self._effective_config.parse_config(self._tag_config.get_dict_format()) self._effective_config += self._builtin_config
def _initialize_tag_config(): tag_config = cmk.gui.tags.TagConfig() tag_config.parse_config({ 'aux_tags': [], 'tag_groups': [ { 'id': 'criticality', 'tags': [{ 'aux_tags': [], 'id': 'prod', 'title': u'Productive system' }, { 'aux_tags': [], 'id': 'critical', 'title': u'Business critical' }, { 'aux_tags': [], 'id': 'test', 'title': u'Test system' }, { 'aux_tags': [], 'id': 'offline', 'title': u'Do not monitor this host' }], 'title': u'Criticality' }, { 'id': 'networking', 'tags': [{ 'aux_tags': [], 'id': 'lan', 'title': u'Local network (low latency)' }, { 'aux_tags': [], 'id': 'wan', 'title': u'WAN (high latency)' }, { 'aux_tags': [], 'id': 'dmz', 'title': u'DMZ (low latency, secure access)' }], 'title': u'Networking Segment' }, ], }) TagConfigFile().save(tag_config.get_dict_format()) # Make sure the host tag attributes are immediately declared! config.tags = tag_config
def test_cfg(test_pre_16_cfg): multisite_dir = Path(cmk.gui.watolib.utils.multisite_dir()) tags_mk = multisite_dir / "tags.mk" hosttags_mk = multisite_dir / "hosttags.mk" with tags_mk.open("w", encoding="utf-8") as f: # pylint: disable=no-member f.write(u"""# Created by WATO # encoding: utf-8 wato_tags = %s """ % repr(test_pre_16_cfg.get_dict_format())) with hosttags_mk.open("w", encoding="utf-8") as f: # pylint: disable=no-member f.write(u"") cfg = tags.TagConfig() cfg.parse_config(TagConfigFile().load_for_reading()) yield cfg if tags_mk.exists(): # pylint: disable=no-member tags_mk.unlink() # pylint: disable=no-member
def test_cfg(): multisite_dir = Path(cmk.gui.watolib.utils.multisite_dir()) tags_mk = multisite_dir / "tags.mk" hosttags_mk = multisite_dir / "hosttags.mk" with tags_mk.open("w", encoding="utf-8") as f: f.write( """# Created by WATO # encoding: utf-8 wato_tags = %s """ % repr(_tag_test_cfg()) ) with hosttags_mk.open("w", encoding="utf-8") as f: f.write("") cfg = tags.TagConfig.from_config(TagConfigFile().load_for_reading()) yield cfg if tags_mk.exists(): tags_mk.unlink()
def _initialize_tag_config(self): tag_config = cmk.utils.tags.TagConfig() tag_config.parse_config(cmk.utils.tags.sample_tag_config()) TagConfigFile().save(tag_config.get_dict_format()) # Make sure the host tag attributes are immediately declared! config.tags = tag_config
def __init__(self): super(ABCTagMode, self).__init__() self._tag_config_file = TagConfigFile() self._load_effective_config()
class ModeTags(WatoMode): @classmethod def name(cls): return "tags" @classmethod def permissions(cls): return ["hosttags"] def __init__(self): super(ModeTags, self).__init__() self._builtin_config = config.BuiltinTagConfig() self._tag_config_file = TagConfigFile() self._tag_config = cmk.gui.tags.TagConfig() self._tag_config.parse_config(self._tag_config_file.load_for_reading()) self._effective_config = cmk.gui.tags.TagConfig() self._effective_config.parse_config(self._tag_config.get_dict_format()) self._effective_config += self._builtin_config def title(self): return _("Tag groups") def buttons(self): global_buttons() html.context_button( _("New tag group"), watolib.folder_preserving_link([("mode", "edit_tag")]), "new") html.context_button( _("New aux tag"), watolib.folder_preserving_link([("mode", "edit_auxtag")]), "new") def action(self): if html.request.has_var("_delete"): return self._delete_tag_group() if html.request.has_var("_del_aux"): return self._delete_aux_tag() if html.request.var("_move") and html.check_transaction(): return self._move_tag_group() def _delete_tag_group(self): del_id = html.get_item_input("_delete", dict(self._tag_config.get_tag_group_choices()))[1] tag_group = self._tag_config.get_tag_group(del_id) if tag_group: operations = list(tag_group.get_tag_ids()) else: operations = None message = _rename_tags_after_confirmation(del_id, operations) if message is True: # no confirmation yet c = wato_confirm( _("Confirm deletion of the tag group '%s'") % del_id, _("Do you really want to delete the tag group '%s'?") % del_id) if c is False: return "" elif c is None: return None if message: self._tag_config.remove_tag_group(del_id) self._tag_config.validate_config() self._tag_config_file.save(self._tag_config.get_dict_format()) watolib.Folder.invalidate_caches() watolib.Folder.root_folder().rewrite_hosts_files() add_change("edit-tags", _("Removed tag group %s (%s)") % (message, del_id)) return "tags", message != True and message or None def _delete_aux_tag(self): del_id = html.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) operations = {del_id: False} message = _rename_tags_after_confirmation(None, operations) if message is True: # no confirmation yet c = wato_confirm( _("Confirm deletion of the auxiliary tag '%s'") % del_id, _("Do you really want to delete the auxiliary tag '%s'?") % del_id) if c is False: return "" elif c is None: return None if message: self._tag_config.aux_tag_list.remove(del_id) self._tag_config.validate_config() self._tag_config_file.save(self._tag_config.get_dict_format()) watolib.Folder.invalidate_caches() watolib.Folder.root_folder().rewrite_hosts_files() add_change("edit-tags", _("Removed auxiliary tag %s (%s)") % (message, del_id)) return "tags", message != True and message or None def _move_tag_group(self): move_nr = html.get_integer_input("_move") move_to = html.get_integer_input("_index") moved = self._tag_config.tag_groups.pop(move_nr) self._tag_config.tag_groups.insert(move_to, moved) self._tag_config.validate_config() self._tag_config_file.save(self._tag_config.get_dict_format()) watolib.add_change("edit-tags", _("Changed order of tag groups")) def page(self): if not self._tag_config.tag_groups + self._tag_config.get_aux_tags(): MainMenu([ MenuItem( "edit_ttag", _("Create new tag group"), "new", "hosttags", _("Each tag group will create one dropdown choice in the host configuration.")), MenuItem( "edit_auxtag", _("Create new auxiliary tag"), "new", "hosttags", _("You can have these tags automatically added if certain primary tags are set." )), ]).show() return self._render_tag_list() self._render_aux_tag_list() def _render_tag_list(self): with table_element( "tags", _("Tag groups"), help=(_("Tags are the basis of Check_MK's rule based configuration. " "If the first step you define arbitrary tag groups. A host " "has assigned exactly one tag out of each group. These tags can " "later be used for defining parameters for hosts and services, " "such as <i>disable notifications for all hosts with the tags " "<b>Network device</b> and <b>Test</b></i>.")), empty_text=_("You haven't defined any tag groups yet."), searchable=False, sortable=False) as table: for nr, tag_group in enumerate(self._effective_config.tag_groups): table.row() table.cell(_("Actions"), css="buttons") self._show_tag_icons(tag_group, nr) table.text_cell(_("ID"), tag_group.id) table.text_cell(_("Title"), tag_group.title) table.text_cell(_("Topic"), tag_group.topic or _("Tags")) table.cell(_("Demonstration"), sortable=False) html.begin_form("tag_%s" % tag_group.id) watolib.host_attribute("tag_%s" % tag_group.id).render_input("", None) html.end_form() def _show_tag_icons(self, tag_group, nr): if self._builtin_config.tag_group_exists(tag_group.id): html.i("(%s)" % _("builtin")) return edit_url = watolib.folder_preserving_link([("mode", "edit_tag"), ("edit", tag_group.id)]) html.icon_button(edit_url, _("Edit this tag group"), "edit") html.element_dragger_url("tr", base_url=make_action_link([("mode", "tags"), ("_move", nr)])) delete_url = make_action_link([("mode", "tags"), ("_delete", tag_group.id)]) html.icon_button(delete_url, _("Delete this tag group"), "delete") def _render_aux_tag_list(self): with table_element( "auxtags", _("Auxiliary tags"), help=_("Auxiliary tags can be attached to other tags. That way " "you can for example have all hosts with the tag <tt>cmk-agent</tt> " "get also the tag <tt>tcp</tt>. This makes the configuration of " "your hosts easier."), empty_text=_("You haven't defined any auxiliary tags."), searchable=False) as table: for aux_tag in self._effective_config.aux_tag_list.get_tags(): table.row() table.cell(_("Actions"), css="buttons") if aux_tag.id in self._builtin_config.aux_tag_list.get_tag_ids(): html.i("(%s)" % _("builtin")) else: edit_url = watolib.folder_preserving_link([("mode", "edit_auxtag"), ("edit", aux_tag.id)]) delete_url = make_action_link([("mode", "tags"), ("_del_aux", aux_tag.id)]) html.icon_button(edit_url, _("Edit this auxiliary tag"), "edit") html.icon_button(delete_url, _("Delete this auxiliary tag"), "delete") table.text_cell(_("ID"), aux_tag.id) table.text_cell(_("Title"), _u(aux_tag.title)) table.text_cell(_("Topic"), _u(aux_tag.topic) or _("Tags")) table.text_cell( _("Tags using this auxiliary tag"), ", ".join( self._get_tags_using_aux_tag(aux_tag))) def _get_tags_using_aux_tag(self, aux_tag): used_tags = set() for tag_group in self._effective_config.tag_groups: for tag in tag_group.tags: if aux_tag in tag.aux_tag_ids: used_tags.add(aux_tag.id) return sorted(used_tags)
class ABCEditTagMode(WatoMode): __metaclass__ = abc.ABCMeta @classmethod def permissions(cls): return ["hosttags"] def __init__(self): super(ABCEditTagMode, self).__init__() self._tag_config_file = TagConfigFile() self._untainted_hosttags_config = cmk.gui.tags.TagConfig() self._untainted_hosttags_config.parse_config(self._tag_config_file.load_for_reading()) self._effective_config = cmk.gui.tags.TagConfig() self._effective_config.parse_config(self._untainted_hosttags_config.get_dict_format()) self._effective_config += cmk.gui.config.BuiltinTagConfig() self._id = self._get_id() self._new = self._is_new_tag() @abc.abstractmethod def _get_id(self): raise NotImplementedError() def _is_new_tag(self): return html.request.var("edit") is None def _basic_elements(self): if self._new: vs_id = ID( title=_("Tag ID"), size=60, allow_empty=False, help=_("The internal ID of the tag is used as it's unique identifier " "It cannot be changed later."), ) else: vs_id = FixedValue( self._id, title=_("Tag ID"), ) return [ ("id", vs_id), ("title", TextUnicode( title=_("Title"), size=60, allow_empty=False, )), ("topic", self._get_topic_valuespec()), ] def _get_topic_valuespec(self): return OptionalDropdownChoice( title=_("Topic") + "<sup>*</sup>", choices=self._effective_config.get_topic_choices(), explicit=TextUnicode(), otherlabel=_("Create new topic"), default_value=None, help=_("Different tags can be grouped in topics to make the visualization and " "selections in the GUI more comfortable."), )
def __init__(self) -> None: super().__init__() self._tag_config_file = TagConfigFile() self._load_effective_config()
def _initialize_tag_config(self) -> None: tag_config = TagConfig.from_config(sample_tag_config()) TagConfigFile().save(tag_config.get_dict_format())
def _initialize_tag_config(self): tag_config = TagConfig() tag_config.parse_config(sample_tag_config()) TagConfigFile().save(tag_config.get_dict_format())