Example #1
0
    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
Example #2
0
    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"))
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
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()
Example #7
0
 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
Example #8
0
 def __init__(self):
     super(ABCTagMode, self).__init__()
     self._tag_config_file = TagConfigFile()
     self._load_effective_config()
Example #9
0
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)
Example #10
0
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."),
        )
Example #11
0
 def __init__(self) -> None:
     super().__init__()
     self._tag_config_file = TagConfigFile()
     self._load_effective_config()
Example #12
0
 def _initialize_tag_config(self) -> None:
     tag_config = TagConfig.from_config(sample_tag_config())
     TagConfigFile().save(tag_config.get_dict_format())
Example #13
0
 def _initialize_tag_config(self):
     tag_config = TagConfig()
     tag_config.parse_config(sample_tag_config())
     TagConfigFile().save(tag_config.get_dict_format())