Пример #1
0
def do_log_ack(site, host_name, file_name):
    sites.live().set_auth_domain("action")

    logs_to_ack = []
    if not host_name and not file_name:  # all logs on all hosts
        for this_site, this_host, logs in all_logs():
            for int_filename in logs:
                file_display = form_file_to_ext(int_filename)
                logs_to_ack.append(
                    (this_site, this_host, int_filename, file_display))

    elif host_name and not file_name:  # all logs on one host
        for int_filename in logfiles_of_host(site, host_name):
            file_display = form_file_to_ext(int_filename)
            logs_to_ack.append((site, host_name, int_filename, file_display))

    elif host_name and file_name:  # one log on one host
        int_filename = form_file_to_int(file_name)
        logs_to_ack = [(site, host_name, int_filename,
                        form_file_to_ext(int_filename))]

    else:
        for this_site, this_host, logs in all_logs():
            file_display = form_file_to_ext(file_name)
            if file_name in logs:
                logs_to_ack.append(
                    (this_site, this_host, file_name, file_display))

    ack_msg = _get_ack_msg(host_name, file_name)
    ack = request.var("_ack")

    if not user.may("general.act"):
        html.h1(_("Permission denied"), class_=["error"])
        html.div(_("You are not allowed to acknowledge %s") % ack_msg,
                 class_=["error"])
        html.footer()
        return

    # filter invalid values
    if ack != "1":
        raise MKUserError("_ack", _("Invalid value for ack parameter."))

    for this_site, this_host, int_filename, display_name in logs_to_ack:
        try:
            acknowledge_logfile(this_site, this_host, int_filename,
                                display_name)
        except Exception as e:
            html.show_error(
                _("The log file <tt>%s</tt> of host <tt>%s</tt> could not be deleted: %s."
                  ) % (display_name, this_host, e))
            html.footer()
            return

    html.show_message("<b>%s</b><p>%s</p>" %
                      (_("Acknowledged %s") % ack_msg,
                       _("Acknowledged all messages in %s.") % ack_msg))
    html.footer()
Пример #2
0
    def filter_table(self, context: VisualContext, rows: Rows) -> Rows:
        from_value = utils.saveint(request.var(self.ident + "_from"))
        to_value = utils.saveint(request.var(self.ident + "_to"))

        if not from_value and not to_value:
            return rows

        newrows = []
        for row in rows:
            value = row.get(self.ident, None)
            if value is not None:
                if from_value and value < from_value:
                    continue

                if to_value and value > to_value:
                    continue
                newrows.append(row)
        return newrows
Пример #3
0
 def needs_validation(self, for_what: str, new: bool) -> bool:
     """Check whether this attribute needs to be validated at all
     Attributes might be permanently hidden (show_in_form = False)
     or dynamically hidden by the depends_on_tags, editable features"""
     if not self.is_visible(for_what, new):
         return False
     if not html:
         return True
     return request.var("attr_display_%s" % self.name(), "1") == "1"
Пример #4
0
    def _get_host_info_from_row(self, row, row_num):
        host_name = None
        attributes: Dict[str, str] = {}
        for col_num, value in enumerate(row):
            if not value:
                continue

            attribute = request.var("attribute_%d" % col_num)
            if attribute == "host_name":
                Hostname().validate_value(value, "host")
                host_name = value

            elif attribute and attribute != "-":
                if attribute in attributes:
                    raise MKUserError(
                        None,
                        _('The attribute "%s" is assigned to multiple columns. '
                          "You can not populate one attribute from multiple columns. "
                          "The column to attribute associations need to be unique."
                          ) % attribute,
                    )

                attr = host_attribute_registry[attribute]()

                # TODO: The value handling here is incorrect. The correct way would be to use the
                # host attributes from_html_vars and validate_input, just like collect_attributes()
                # from cmk/gui/watolib/host_attributes.py is doing it.
                # The problem here is that we get the value in a different way (from row instead of
                # HTTP request vars) which from_html_vars can not work with.

                if attribute == "alias":
                    attributes[attribute] = value
                else:
                    if not value.isascii():
                        raise MKUserError(
                            None,
                            _("Non-ASCII characters are not allowed in the "
                              'attribute "%s".') % attribute,
                        )

                    try:
                        attr.validate_input(value, "")
                    except MKUserError as e:
                        raise MKUserError(
                            None,
                            _("Invalid value in column %d (%s) of row %d: %s")
                            % (col_num, attribute, row_num, e),
                        )

                    attributes[attribute] = value

        if host_name is None:
            raise MKUserError(
                None,
                _("The host name attribute needs to be assigned to a column."))

        return host_name, attributes
Пример #5
0
 def display(self):
     current = request.var(self.varname)
     html.begin_radio_group(horizontal=True)
     for value, text in [("1", _("yes")), ("0", _("no")),
                         ("-1", _("(ignore)"))]:
         checked = current == value or (current in [None, ""]
                                        and int(value) == self.deflt)
         html.radiobutton(self.varname, value, checked, text + u" &nbsp; ")
     html.end_radio_group()
Пример #6
0
    def _get_hostnames_from_filters(self) -> Set[HostName]:
        # Determine hosts from filters
        filter_headers = self._get_filter_headers()
        query = "GET hosts\nColumns: name"
        if filter_headers:
            query += "\n%s" % filter_headers

        with sites.only_sites(request.var("site")):
            return {HostName(x[0]) for x in sites.live().query(query)}
Пример #7
0
def ajax_message_read():
    response.set_content_type("application/json")
    try:
        message.delete_gui_message(request.var("id"))
        html.write_text("OK")
    except Exception:
        if config.debug:
            raise
        html.write_text("ERROR")
Пример #8
0
    def action(self) -> ActionResult:
        if not transactions.transaction_valid():
            return redirect(mode_url("folder"))

        attributes = watolib.collect_attributes(self._host_type_name(),
                                                new=True)
        cluster_nodes = self._get_cluster_nodes()

        hostname = request.get_ascii_input_mandatory("host")
        Hostname().validate_value(hostname, "host")

        folder = watolib.Folder.current()

        if transactions.check_transaction():
            folder.create_hosts([(hostname, attributes, cluster_nodes)])

        self._host = folder.host(hostname)

        inventory_url = watolib.folder_preserving_link([
            ("mode", "inventory"),
            ("host", self._host.name()),
            ("_scan", "1"),
        ])

        create_msg = (None if self._host.is_ping_host() else (
            _("Successfully created the host. Now you should do a "
              '<a href="%s">service discovery</a> in order to auto-configure '
              "all services to be checked on this host.") % inventory_url))

        if request.var("services"):
            raise redirect(inventory_url)

        if request.var("diag_host"):
            if create_msg:
                flash(create_msg)
            return redirect(
                mode_url("diag_host",
                         folder=folder.path(),
                         host=self._host.name(),
                         _try="1"))

        if create_msg:
            flash(create_msg)
        return redirect(mode_url("folder", folder=folder.path()))
Пример #9
0
    def action(self) -> ActionResult:
        if transactions.transaction_valid():
            if request.has_var("_do_upload"):
                self._upload_csv_file()

            csv_reader = self._open_csv_file()

            if request.var("_do_import"):
                return self._import(csv_reader)
        return None
Пример #10
0
    def action(self) -> ActionResult:
        folder = watolib.Folder.current()
        if not transactions.check_transaction():
            return redirect(mode_url("folder", folder=folder.path()))

        if request.var("_update_dns_cache") and self._should_use_dns_cache():
            user.need_permission("wato.update_dns_cache")
            update_dns_cache_result = update_dns_cache(self._host.site_id())
            infotext = (
                _("Successfully updated IP addresses of %d hosts.")
                % update_dns_cache_result.n_updated
            )
            if update_dns_cache_result.failed_hosts:
                infotext += "<br><br><b>Hostnames failed to lookup:</b> " + ", ".join(
                    ["<tt>%s</tt>" % h for h in update_dns_cache_result.failed_hosts]
                )
            flash(infotext)
            return None

        if request.var("delete"):  # Delete this host
            folder.delete_hosts([self._host.name()])
            return redirect(mode_url("folder", folder=folder.path()))

        attributes = watolib.collect_attributes(
            "host" if not self._is_cluster() else "cluster", new=False
        )
        host = watolib.Host.host(self._host.name())
        if host is None:
            flash(f"Host {self._host.name()} could not be found.")
            return None

        host.edit(attributes, self._get_cluster_nodes())
        self._host = folder.load_host(self._host.name())

        if request.var("_save"):
            return redirect(mode_url("inventory", folder=folder.path(), host=self._host.name()))
        if request.var("diag_host"):
            return redirect(
                mode_url(
                    "diag_host", folder=folder.path(), host=self._host.name(), _start_on_load="1"
                )
            )
        return redirect(mode_url("folder", folder=folder.path()))
Пример #11
0
def ajax_render_tree():
    aggr_group = request.get_str_input("group")
    aggr_title = request.get_str_input("title")
    omit_root = bool(request.var("omit_root"))
    only_problems = bool(request.var("only_problems"))

    rows = []
    bi_manager = BIManager()
    bi_manager.status_fetcher.set_assumed_states(user.bi_assumptions)
    aggregation_id = request.get_str_input_mandatory("aggregation_id")
    bi_aggregation_filter = BIAggregationFilter(
        [],
        [],
        [aggregation_id],
        [aggr_title] if aggr_title is not None else [],
        [aggr_group] if aggr_group is not None else [],
        [],
    )
    rows = bi_manager.computer.compute_legacy_result_for_filter(
        bi_aggregation_filter)

    # TODO: Cleanup the renderer to use a class registry for lookup
    renderer_class_name = request.var("renderer")
    if renderer_class_name == "FoldableTreeRendererTree":
        renderer_cls: Type[ABCFoldableTreeRenderer] = FoldableTreeRendererTree
    elif renderer_class_name == "FoldableTreeRendererBoxes":
        renderer_cls = FoldableTreeRendererBoxes
    elif renderer_class_name == "FoldableTreeRendererBottomUp":
        renderer_cls = FoldableTreeRendererBottomUp
    elif renderer_class_name == "FoldableTreeRendererTopDown":
        renderer_cls = FoldableTreeRendererTopDown
    else:
        raise NotImplementedError()

    renderer = renderer_cls(
        rows[0],
        omit_root=omit_root,
        expansion_level=user.bi_expansion_level,
        only_problems=only_problems,
        lazy=False,
    )
    html.write_html(renderer.render())
Пример #12
0
    def filter_table(self, context: VisualContext, rows: Rows) -> Rows:
        current = request.var(self.ident)
        if current not in ("1", "2"):
            return rows

        new_rows = []
        for row in rows:
            admin_status = str(row["invinterface_admin_status"])
            if admin_status == current:
                new_rows.append(row)
        return new_rows
Пример #13
0
def ajax_save_treestate():
    path_id = request.get_unicode_input_mandatory("path")
    current_ex_level_str, path = path_id.split(":", 1)
    current_ex_level = int(current_ex_level_str)

    if config.user.bi_expansion_level != current_ex_level:
        config.user.set_tree_states('bi', {})
    config.user.set_tree_state('bi', path, request.var("state") == "open")
    config.user.save_tree_states()

    config.user.bi_expansion_level = current_ex_level
Пример #14
0
    def display(self) -> None:
        html.write_text(_("From: "))
        htmlvar = self.htmlvars[0]
        current_value = request.var(htmlvar, "")
        html.text_input(htmlvar,
                        default_value=str(current_value),
                        size=8,
                        cssclass="number")
        if self._unit:
            html.write_text(" %s" % self._unit)

        html.write_text("&nbsp;&nbsp;" + _("To: "))
        htmlvar = self.htmlvars[1]
        current_value = request.var(htmlvar, "")
        html.text_input(htmlvar,
                        default_value=str(current_value),
                        size=8,
                        cssclass="number")
        if self._unit:
            html.write_text(" %s" % self._unit)
Пример #15
0
def page_show():
    site = request.var("site")  # optional site hint
    host_name = request.var("host", "")
    file_name = request.get_unicode_input("file", "")

    # Fix problem when URL is missing certain illegal characters
    try:
        file_name = form_file_to_ext(
            find_matching_logfile(site, host_name, form_file_to_int(file_name)))
    except livestatus.MKLivestatusNotFoundError:
        pass  # host_name log dir does not exist

    if not host_name:
        show_log_list()
        return

    if file_name:
        show_file(site, host_name, file_name)
    else:
        show_host_log_list(site, host_name)
Пример #16
0
def ajax_save_treestate():
    path_id = request.get_str_input_mandatory("path")
    current_ex_level_str, path = path_id.split(":", 1)
    current_ex_level = int(current_ex_level_str)

    if user.bi_expansion_level != current_ex_level:
        user.set_tree_states("bi", {})
    user.set_tree_state("bi", path, request.var("state") == "open")
    user.save_tree_states()

    user.bi_expansion_level = current_ex_level
Пример #17
0
    def _from_vars(self):
        self._start = bool(request.var("_start"))
        # 'all' not set -> only scan checked hosts in current folder, no recursion
        # otherwise: all host in this folder, maybe recursively
        self._all = bool(request.var("all"))
        self._complete_folder = self._all

        # Ignored during initial form display
        self._settings = ParentScanSettings(
            where=request.get_ascii_input_mandatory("where", "subfolder"),
            alias=request.get_unicode_input_mandatory("alias", "").strip(),
            recurse=html.get_checkbox("recurse") or False,
            select=request.get_ascii_input_mandatory("select", "noexplicit"),
            timeout=request.get_integer_input_mandatory("timeout", 8),
            probes=request.get_integer_input_mandatory("probes", 2),
            max_ttl=request.get_integer_input_mandatory("max_ttl", 10),
            force_explicit=html.get_checkbox("force_explicit") or False,
            ping_probes=request.get_integer_input_mandatory("ping_probes", 5),
        )
        self._job = ParentScanBackgroundJob()
Пример #18
0
    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.
        watolib.add_change(
            "changes-discarded",
            msg,
            domains=watolib.ABCConfigDomain.enabled_domains(),
            need_restart=True,
        )

        self._extract_snapshot(file_to_restore)
        activate_changes.execute_activate_changes([
            d.get_domain_request([])
            for d in watolib.ABCConfigDomain.enabled_domains()
        ])

        for site_id in activation_sites():
            self.confirm_site_changes(site_id)

        build_index_background()

        html.header(
            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)
Пример #19
0
    def _ajax_tag_tree(self):
        response.set_content_type("application/json")
        self._load()
        new_tree = request.var("tree_id")

        if new_tree not in self._trees:
            raise MKUserError("conf", _("This virtual host tree does not exist."))

        self._current_tree_id = new_tree
        self._save_user_settings()
        response.set_data("OK")
Пример #20
0
    def action(self) -> ActionResult:
        if not transactions.check_transaction():
            return None

        if request.var('_try'):
            try:
                self._validate_diag_html_vars()
            except MKUserError as e:
                user_errors.add(e)
            return None

        if request.var('_save'):
            # Save the ipaddress and/or community
            vs_host = self._vs_host()
            new = vs_host.from_html_vars('vs_host')
            vs_host.validate_value(new, 'vs_host')

            # If both snmp types have credentials set - snmpv3 takes precedence
            return_message = []
            if "ipaddress" in new:
                return_message.append(_("IP address"))
            if "snmp_v3_credentials" in new:
                if "snmp_community" in new:
                    return_message.append(
                        _("SNMPv3 credentials (SNMPv2 community was discarded)"
                          ))
                else:
                    return_message.append(_("SNMPv3 credentials"))
                new["snmp_community"] = new["snmp_v3_credentials"]
            elif "snmp_community" in new:
                return_message.append(_("SNMP credentials"))

            self._host.update_attributes(new)
            flash(_("Updated attributes: ") + ", ".join(return_message))
            return redirect(
                mode_url(
                    "edit_host",
                    host=self._hostname,
                    folder=watolib.Folder.current().path(),
                ))
        return None
Пример #21
0
    def action(self) -> ActionResult:
        if request.var("_action") == "clear":
            user.need_permission("wato.auditlog")
            user.need_permission("wato.clear_auditlog")
            user.need_permission("wato.edit")
            return self._clear_audit_log_after_confirm()

        if html.request.var("_action") == "csv":
            user.need_permission("wato.auditlog")
            return self._export_audit_log(self._parse_audit_log())

        return None
Пример #22
0
    def _resolve_site(host):
        # When the site is available via URL context, use it. Otherwise it is needed
        # to check all sites for the requested host
        if request.has_var('site'):
            return request.var('site')

        with sites.prepend_site():
            query = "GET hosts\nFilter: name = %s\nColumns: name" % livestatus.lqencode(host)
            try:
                return sites.live().query_value(query)
            except livestatus.MKLivestatusNotFoundError:
                raise MKUserError("host", _("The host could not be found on any active site."))
Пример #23
0
 def heading_info(self):
     # FIXME: There is a problem with caching data and changing titles of WATO files
     # Everything is changed correctly but the filter object is stored in the
     # global multisite_filters var and self.path_to_tree is not refreshed when
     # rendering this title. Thus the threads might have old information about the
     # file titles and so on.
     # The call below needs to use some sort of indicator wether the cache needs
     # to be renewed or not.
     self.check_wato_data_update()
     current = request.var(self.ident)
     if current and current != "/":
         return self.path_to_tree.get(current)
Пример #24
0
def ajax_set_assumption() -> None:
    site = request.get_str_input("site")
    host = request.get_str_input("host")
    service = request.get_str_input("service")
    state = request.var("state")
    if state == "none":
        del user.bi_assumptions[_get_state_assumption_key(site, host, service)]
    elif state is not None:
        user.bi_assumptions[_get_state_assumption_key(site, host, service)] = int(state)
    else:
        raise Exception("ajax_set_assumption: state is None")
    user.save_bi_assumptions()
Пример #25
0
    def _from_vars(self):
        self._timeperiods = watolib.timeperiods.load_timeperiods()
        self._name = request.var("edit")  # missing -> new group
        # TODO: Nuke the field below? It effectively hides facts about _name for mypy.
        self._new = self._name is None

        if self._name in watolib.timeperiods.builtin_timeperiods():
            raise MKUserError("edit", _("Builtin timeperiods can not be modified"))
        if self._new:
            clone_name = request.var("clone")
            if request.var("mode") == "import_ical":
                self._timeperiod = {}
            elif clone_name:
                self._name = clone_name

                self._timeperiod = self._get_timeperiod(self._name)
            else:
                # initialize with 24x7 config
                self._timeperiod = {day: [("00:00", "24:00")] for day in defines.weekday_ids()}
        else:
            self._timeperiod = self._get_timeperiod(self._name)
Пример #26
0
    def page(self) -> None:
        acktime = request.get_float_input_mandatory("acktime", time.time())
        if request.var("_confirm"):
            _acknowledge_failed_notifications(acktime, time.time())

            if user.authorized_login_sites():
                title = _("Replicate user profile")
                breadcrumb = make_simple_page_breadcrumb(
                    mega_menu_registry.menu_monitoring(), title
                )
                html.header(title, breadcrumb)

                for message in get_flashed_messages():
                    html.show_message(message)
                user_profile_async_replication_page(back_url="clear_failed_notifications.py")
                return

        failed_notifications = load_failed_notifications(before=acktime, after=acknowledged_time())
        self._show_page(acktime, failed_notifications)
        if request.var("_confirm"):
            html.reload_whole_page()
Пример #27
0
    def from_html_vars(self, varprefix):
        if request.var(self.tp_current_mode) == "1":
            # Fetch the timespecific settings
            parameters = self._get_timeperiod_valuespec().from_html_vars(
                varprefix)
            if parameters[self.tp_values_key]:
                return parameters

            # Fall back to enclosed valuespec data when no timeperiod is set
            return parameters[self.tp_default_value_key]

        # Fetch the data from the enclosed valuespec
        return self._enclosed_valuespec.from_html_vars(varprefix)
Пример #28
0
    def delete_job(self):
        job_id = request.var(self.delete_job_var)
        if not job_id:
            return

        job = GUIBackgroundJob(job_id=job_id)
        if not job.is_available():
            return

        if job.may_delete():
            job.delete()
            self._did_delete_job = True
            html.show_message(_("Background job has been deleted"))
Пример #29
0
    def _from_vars(self) -> None:
        user.need_permission("wato.download_agent_output")

        host_name = request.var("host")
        if not host_name:
            raise MKGeneralException(_("The host is missing."))

        ty = request.var("type")
        if ty not in ["walk", "agent"]:
            raise MKGeneralException(_("Invalid type specified."))

        self._back_url = request.get_url_input("back_url", deflt="") or None

        host = watolib.Folder.current().host(host_name)
        if not host:
            raise MKGeneralException(
                _("Host is not managed by WATO. "
                  'Click <a href="%s">here</a> to go back.') %
                escape_attribute(self._back_url))
        host.need_permission("read")

        self._request = FetchAgentOutputRequest(host=host, agent_type=ty)
Пример #30
0
    def filter_table(self, context: VisualContext, rows: Rows) -> Rows:
        current = request.var(self.ident)
        if current not in ("no", "yes"):
            return rows

        f = current == "yes"

        new_rows = []
        for row in rows:
            available = row.get("invinterface_available")
            if available == f:
                new_rows.append(row)
        return new_rows