def stop_job(self):
        job_id = html.request.var(self.stop_job_var)
        if not job_id:
            return

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

        title = _("Interuption of job")
        html.header(title, self._breadcrumb)
        if self.confirm_dialog_opened() and not job.is_active():
            html.show_message(_("No longer able to stop job. Background job just finished."))
            return

        c = html.confirm(_("Stop job %s%s?") % (job_id, self._get_extra_info(job)))
        if c and job.may_stop():
            job.stop()
            self._did_stop_job = True
            html.show_message(_("Background job has been stopped"))
Exemple #2
0
    def page(self) -> None:
        watolib.init_wato_datastructures(with_wato_lock=True)

        title = self._page_title()
        breadcrumb = make_simple_page_breadcrumb(
            mega_menu_registry.menu_user(), title)
        html.header(title, breadcrumb, self._page_menu(breadcrumb))

        if html.request.has_var('_save') and transactions.check_transaction():
            try:
                self._action()
            except MKUserError as e:
                user_errors.add(e)

        for message in get_flashed_messages():
            html.show_message(message)

        html.show_user_errors()

        self._show_form()
Exemple #3
0
    def page(self):
        job_id = html.request.var("job_id")

        job = gui_background_job.GUIBackgroundJob(job_id)
        if not job.exists():
            html.show_message(_("Background job info is not available"))
            return

        try:
            # Race condition, the job might get deleted during snapshot generation
            job_snapshot = job.get_status_snapshot()
        except Exception:
            html.show_message(_("Background job info is not available"))
            logger.error(traceback.format_exc())
            return

        job_manager = gui_background_job.GUIBackgroundJobManager()
        job_manager.show_job_details_from_snapshot(job_snapshot)
        if job_snapshot.is_active():
            html.immediate_browser_redirect(1, "")
Exemple #4
0
    def page(self):
        if not self._analyze_sites():
            html.show_message(
                _("Analyze configuration can only be used with the local site and "
                  "distributed WATO slave sites. You currently have no such site configured."))
            return

        results_by_category = self._perform_tests()

        site_ids = sorted(self._analyze_sites())

        for category_name, results_by_test in sorted(results_by_category.items(),
                                                     key=lambda x: ACTestCategories.title(x[0])):
            with table_element(title=ACTestCategories.title(category_name),
                               css="data analyze_config",
                               sortable=False,
                               searchable=False) as table:

                for test_id, test_results_by_site in sorted(results_by_test.items(),
                                                            key=lambda x: x[1]["test"]["title"]):
                    self._show_test_row(table, test_id, test_results_by_site, site_ids)
Exemple #5
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()
Exemple #6
0
    def _patch_page(self) -> None:
        breadcrumb = _release_notes_breadcrumb()

        load_werks()
        werk_table_options = _werk_table_options_from_request()

        html.header(self._title(),
                    breadcrumb,
                    _release_notes_page_menu(breadcrumb, werk_table_options),
                    page_state=_release_switch(major=False))

        for message in get_flashed_messages():
            html.show_message(message)

        handle_acknowledgement()

        html.open_div(class_="wato")
        render_werks_table(werk_table_options)
        html.close_div()

        html.footer()
Exemple #7
0
    def page(self) -> cmk.gui.pages.PageResult:
        breadcrumb = make_simple_page_breadcrumb(mega_menu_registry["help_links"], self._title())

        load_werks()
        werk_table_options = _werk_table_options_from_request()

        html.header(
            self._title(),
            breadcrumb,
            self._page_menu(breadcrumb, werk_table_options),
        )

        for message in get_flashed_messages():
            html.show_message(message)

        handle_acknowledgement()

        html.open_div(class_="wato")
        render_werks_table(werk_table_options)
        html.close_div()

        html.footer()
Exemple #8
0
def handle_acknowledgement():
    if not transactions.check_transaction():
        return

    if request.var("_werk_ack"):
        werk_id = request.get_integer_input_mandatory("_werk_ack")
        if werk_id not in g_werks:
            raise MKUserError("werk", _("This werk does not exist."))
        werk = g_werks[werk_id]

        if werk["compatible"] == "incomp_unack":
            acknowledge_werk(werk)
            html.show_message(
                _("Werk %s - %s has been acknowledged.") % (render_werk_id(
                    werk, with_link=True), render_werk_title(werk)))
            load_werks()  # reload ack states after modification
            render_unacknowleged_werks()

    elif request.var("_ack_all"):
        num = len(unacknowledged_incompatible_werks())
        acknowledge_all_werks()
        flash(_("%d incompatible Werks have been acknowledged.") % num)
        load_werks()  # reload ack states after modification
        html.reload_whole_page()
    def _show_configuration_variables(self, groups):
        search = self._search

        at_least_one_painted = False
        html.open_div(class_="globalvars")
        for group in sorted(groups, key=lambda g: g.sort_index()):
            header_is_painted = False  # needed for omitting empty groups

            for config_variable_class in group.config_variables():
                config_variable = config_variable_class()
                varname = config_variable.ident()
                valuespec = config_variable.valuespec()

                if not config_variable.domain().enabled():
                    continue

                if config_variable.domain(
                ) == watolib.ConfigDomainCore and varname not in self._default_values:
                    if config.debug:
                        raise MKGeneralException(
                            "The configuration variable <tt>%s</tt> is unknown to "
                            "your local Check_MK installation" % varname)
                    continue

                if not config_variable.in_global_settings():
                    continue

                if self._show_only_modified and varname not in self._current_settings:
                    continue

                help_text = valuespec.help() or ''
                title_text = valuespec.title()

                if search and search not in group.title().lower() \
                        and search not in config_variable.domain().ident.lower() \
                          and search not in varname \
                          and search not in help_text.lower() \
                          and search not in title_text.lower():
                    continue  # skip variable when search is performed and nothing matches
                at_least_one_painted = True

                if not header_is_painted:
                    # always open headers when searching
                    forms.header(group.title(), isopen=search or self._show_only_modified)
                    header_is_painted = True

                default_value = self._default_values[varname]

                edit_url = watolib.folder_preserving_link([("mode", self._edit_mode()),
                                                           ("varname", varname),
                                                           ("site", html.request.var("site", ""))])
                title = html.render_a(
                    title_text,
                    href=edit_url,
                    class_="modified" if varname in self._current_settings else None,
                    title=escaping.strip_tags(help_text))

                if varname in self._current_settings:
                    value = self._current_settings[varname]
                elif varname in self._global_settings:
                    value = self._global_settings[varname]
                else:
                    value = default_value

                try:
                    to_text = valuespec.value_to_text(value)
                except Exception:
                    logger.exception("error converting %r to text", value)
                    to_text = html.render_error(_("Failed to render value: %r") % value)

                # Is this a simple (single) value or not? change styling in these cases...
                simple = True
                if '\n' in to_text or '<td>' in to_text:
                    simple = False
                forms.section(title, simple=simple)

                if varname in self._current_settings:
                    modified_cls: Optional[str] = "modified"
                    value_title: Optional[str] = _("This option has been modified.")
                elif varname in self._global_settings:
                    modified_cls = "modified globally"
                    value_title = _("This option has been modified in global settings.")
                else:
                    modified_cls = None
                    value_title = None

                if is_a_checkbox(valuespec):
                    html.open_div(class_=["toggle_switch_container", modified_cls])
                    html.toggle_switch(
                        enabled=value,
                        help_txt=_("Immediately toggle this setting"),
                        href=html.makeactionuri([("_action", "toggle"), ("_varname", varname)]),
                        class_=modified_cls,
                        title=value_title,
                    )
                    html.close_div()

                else:
                    html.a(HTML(to_text), href=edit_url, class_=modified_cls, title=value_title)

            if header_is_painted:
                forms.end()
        if not at_least_one_painted and search:
            html.show_message(_('Did not find any global setting matching your search.'))
        html.close_div()
Exemple #10
0
def do_log_ack(site, host_name, file_name):
    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))
        ack_msg = _('all logfiles on all hosts')

    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))
        ack_msg = _('all logfiles of host %s') % host_name

    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))]
        ack_msg = _('the log file %s on host %s') % (file_name, host_name)

    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 = _('log file %s on all hosts') % file_name

    title = _("Acknowledge %s") % html.render_text(ack_msg)

    if host_name:
        breadcrumb = make_host_breadcrumb(host_name)
    else:
        breadcrumb = make_simple_page_breadcrumb(MegaMenuMonitoring, title)

    html.header(title, breadcrumb)

    html.begin_context_buttons()
    button_all_logfiles()
    if host_name:
        html.context_button(_("All Logfiles of Host"),
                            html.makeuri([('file', '')]))
    if host_name and file_name:
        html.context_button(_("Back to Logfile"), html.makeuri([]))
    html.end_context_buttons()

    ack = html.request.var('_ack')
    if not html.confirm(
            _("Do you really want to acknowledge %s by <b>deleting</b> all stored messages?"
              ) % ack_msg):
        html.footer()
        return

    if not config.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()
Exemple #11
0
def show_file(site, host_name, file_name):
    int_filename = form_file_to_int(file_name)

    title = _("Logfiles of Host %s: %s") % (host_name, file_name)
    html.header(title, make_host_breadcrumb(host_name))

    html.begin_context_buttons()
    html.context_button(_("Services"), services_url(site, host_name),
                        'services')
    html.context_button(_("All Logfiles of Host"),
                        html.makeuri([('file', '')]))
    button_all_logfiles()
    html.context_button(_("Analyze patterns"),
                        analyse_url(site, host_name, file_name), 'analyze')

    if html.request.var('_hidecontext', 'no') == 'yes':
        hide_context_label = _('Show Context')
        hide_context_param = 'no'
        hide = True
    else:
        hide_context_label = _('Hide Context')
        hide_context_param = 'yes'
        hide = False

    try:
        log_chunks = parse_file(site, host_name, int_filename, hide)
    except Exception as e:
        if config.debug:
            raise
        html.end_context_buttons()
        html.show_error(_("Unable to show logfile: <b>%s</b>") % e)
        html.footer()
        return

    if log_chunks is None:
        html.end_context_buttons()
        html.show_error(_("The logfile does not exist."))
        html.footer()
        return

    if log_chunks == []:
        html.end_context_buttons()
        html.show_message(
            _("This logfile contains no unacknowledged messages."))
        html.footer()
        return

    ack_button(site, host_name, int_filename)
    html.context_button(hide_context_label,
                        html.makeuri([('_hidecontext', hide_context_param)]))

    html.end_context_buttons()

    html.open_div(id_="logwatch")
    for log in log_chunks:
        html.open_div(class_=["chunk"])
        html.open_table(class_=["section"])
        html.open_tr()
        html.td(form_level(log['level']), class_=form_level(log['level']))
        html.td(form_datetime(log['datetime']), class_="date")
        html.close_tr()
        html.close_table()

        for line in log['lines']:
            html.open_p(class_=line['class'])
            html.icon_button(
                analyse_url(site, host_name, file_name, line['line']),
                _("Analyze this line"), "analyze")
            html.write_text(line['line'].replace(" ", "&nbsp;").replace(
                "\1", "<br>"))
            html.close_p()

        html.close_div()

    html.close_div()
    html.footer()
Exemple #12
0
def _show_page_user_profile(change_pw):
    start_async_replication = False

    if not config.user.id:
        raise MKUserError(None, _('Not logged in.'))

    if not config.user.may('general.edit_profile') and not config.user.may(
            'general.change_password'):
        raise MKAuthException(
            _("You are not allowed to edit your user profile."))

    if not config.wato_enabled:
        raise MKAuthException(
            _('User profiles can not be edited (WATO is disabled).'))

    success = None
    if html.request.has_var('_save') and html.check_transaction():
        users = userdb.load_users(lock=True)

        try:
            # Profile edit (user options like language etc.)
            if config.user.may('general.edit_profile'):
                if not change_pw:
                    set_lang = html.get_checkbox('_set_lang')
                    language = html.request.var('language')
                    # Set the users language if requested
                    if set_lang:
                        if language == '':
                            language = None
                        # Set custom language
                        users[config.user.id]['language'] = language
                        config.user.language = language
                        html.set_language_cookie(language)

                    else:
                        # Remove the customized language
                        if 'language' in users[config.user.id]:
                            del users[config.user.id]['language']
                        config.user.reset_language()

                    # load the new language
                    cmk.gui.i18n.localize(config.user.language)

                    user = users.get(config.user.id)
                    if config.user.may('general.edit_notifications'
                                       ) and user.get("notifications_enabled"):
                        value = forms.get_input(
                            watolib.get_vs_flexible_notifications(),
                            "notification_method")
                        users[config.user.id]["notification_method"] = value

                    # Custom attributes
                    if config.user.may('general.edit_user_attributes'):
                        for name, attr in userdb.get_user_attributes():
                            if attr.user_editable():
                                if not attr.permission() or config.user.may(
                                        attr.permission()):
                                    vs = attr.valuespec()
                                    value = vs.from_html_vars('ua_' + name)
                                    vs.validate_value(value, "ua_" + name)
                                    users[config.user.id][name] = value

            # Change the password if requested
            password_changed = False
            if config.user.may('general.change_password'):
                cur_password = html.request.var('cur_password')
                password = html.request.var('password')
                password2 = html.request.var('password2', '')

                if change_pw:
                    # Force change pw mode
                    if not cur_password:
                        raise MKUserError(
                            "cur_password",
                            _("You need to provide your current password."))
                    if not password:
                        raise MKUserError(
                            "password", _("You need to change your password."))
                    if cur_password == password:
                        raise MKUserError(
                            "password",
                            _("The new password must differ from your current one."
                              ))

                if cur_password and password:
                    if userdb.hook_login(config.user.id,
                                         cur_password) is False:
                        raise MKUserError("cur_password",
                                          _("Your old password is wrong."))
                    if password2 and password != password2:
                        raise MKUserError(
                            "password2",
                            _("The both new passwords do not match."))

                    watolib.verify_password_policy(password)
                    users[config.user.id]['password'] = hash_password(password)
                    users[config.user.id]['last_pw_change'] = int(time.time())

                    if change_pw:
                        # Has been changed, remove enforcement flag
                        del users[config.user.id]['enforce_pw_change']

                    # Increase serial to invalidate old cookies
                    if 'serial' not in users[config.user.id]:
                        users[config.user.id]['serial'] = 1
                    else:
                        users[config.user.id]['serial'] += 1

                    password_changed = True

            # Now, if in distributed environment where users can login to remote sites,
            # set the trigger for pushing the new auth information to the slave sites
            # asynchronous
            if config.user.authorized_login_sites():
                start_async_replication = True

            userdb.save_users(users)

            if password_changed:
                # Set the new cookie to prevent logout for the current user
                login.set_auth_cookie(config.user.id)

            success = True
        except MKUserError as e:
            html.add_user_error(e.varname, e)
    else:
        users = userdb.load_users()

    watolib.init_wato_datastructures(with_wato_lock=True)

    # When in distributed setup, display the replication dialog instead of the normal
    # profile edit dialog after changing the password.
    if start_async_replication:
        user_profile_async_replication_page()
        return

    if change_pw:
        title = _("Change Password")
    else:
        title = _("Edit User Profile")

    html.header(title)

    # Rule based notifications: The user currently cannot simply call the according
    # WATO module due to WATO permission issues. So we cannot show this button
    # right now.
    if not change_pw:
        rulebased_notifications = watolib.load_configuration_settings().get(
            "enable_rulebased_notifications")
        if rulebased_notifications and config.user.may(
                'general.edit_notifications'):
            html.begin_context_buttons()
            url = "wato.py?mode=user_notifications_p"
            html.context_button(_("Notifications"), url, "notifications")
            html.end_context_buttons()
    else:
        reason = html.request.var('reason')
        if reason == 'expired':
            html.p(
                _('Your password is too old, you need to choose a new password.'
                  ))
        else:
            html.p(
                _('You are required to change your password before proceeding.'
                  ))

    if success:
        html.reload_sidebar()
        if change_pw:
            html.show_message(_("Your password has been changed."))
            raise HTTPRedirect(html.request.var('_origtarget', 'index.py'))
        else:
            html.show_message(_("Successfully updated user profile."))
            # Ensure theme changes are applied without additional user interaction
            html.immediate_browser_redirect(0.5, html.makeuri([]))

    if html.has_user_errors():
        html.show_user_errors()

    user = users.get(config.user.id)
    if user is None:
        html.show_warning(_("Sorry, your user account does not exist."))
        html.footer()
        return

    # Returns true if an attribute is locked and should be read only. Is only
    # checked when modifying an existing user
    locked_attributes = userdb.locked_attributes(user.get('connector'))

    def is_locked(attr):
        return attr in locked_attributes

    html.begin_form("profile", method="POST")
    html.prevent_password_auto_completion()
    html.open_div(class_="wato")
    forms.header(_("Personal Settings"))

    if not change_pw:
        forms.section(_("Name"), simple=True)
        html.write_text(user.get("alias", config.user.id))

    if config.user.may(
            'general.change_password') and not is_locked('password'):
        forms.section(_("Current Password"))
        html.password_input('cur_password', autocomplete="new-password")

        forms.section(_("New Password"))
        html.password_input('password', autocomplete="new-password")

        forms.section(_("New Password Confirmation"))
        html.password_input('password2', autocomplete="new-password")

    if not change_pw and config.user.may('general.edit_profile'):
        select_language(user)

        # Let the user configure how he wants to be notified
        if not rulebased_notifications \
            and config.user.may('general.edit_notifications') \
            and user.get("notifications_enabled"):
            forms.section(_("Notifications"))
            html.help(
                _("Here you can configure how you want to be notified about host and service problems and "
                  "other monitoring events."))
            watolib.get_vs_flexible_notifications().render_input(
                "notification_method", user.get("notification_method"))

        if config.user.may('general.edit_user_attributes'):
            for name, attr in userdb.get_user_attributes():
                if attr.user_editable():
                    vs = attr.valuespec()
                    forms.section(_u(vs.title()))
                    value = user.get(name, vs.default_value())
                    if not attr.permission() or config.user.may(
                            attr.permission()):
                        vs.render_input("ua_" + name, value)
                        html.help(_u(vs.help()))
                    else:
                        html.write(vs.value_to_text(value))

    # Save button
    forms.end()
    html.button("_save", _("Save"))
    html.close_div()
    html.hidden_fields()
    html.end_form()
    html.footer()
Exemple #13
0
    def _handle_report_form(self, crash_info):
        details = {}
        try:
            vs = self._vs_crash_report()
            details = vs.from_html_vars("_report")
            vs.validate_value(details, "_report")

            # Make the resulting page execute the crash report post request
            url_encoded_params = urlencode_vars(
                list(details.items()) + [
                    (
                        "crashdump",
                        base64.b64encode(
                            _pack_crash_report(
                                self._get_serialized_crash_report())),
                    ),
                ])
            html.open_div(id_="pending_msg", style="display:none")
            html.show_message(_("Submitting crash report..."))
            html.close_div()
            html.open_div(id_="success_msg", style="display:none")
            html.show_message(
                _("Your crash report has been submitted (ID: ###ID###). Thanks for your participation, "
                  "it is very important for the quality of Checkmk.<br><br>"
                  "Please note:"
                  "<ul>"
                  "<li>In general we do <i>not</i> respond to crash reports, "
                  "except we need further information from you.</li>"
                  "<li>We read every feedback thoroughly, but this might happen "
                  "not before a couple of weeks or even months have passed and is "
                  "often aligned with our release cycle.</li>"
                  "<li>If you are in need of a quick solution for your problem, then "
                  "we can help you within the scope of professional support. If you "
                  "already have a support contract, then please use your personal "
                  "support email address to send us a mail refering to your crash "
                  "report.<br>If you are interested in the details about support, "
                  'you find details on <a href="https://checkmk.com/'
                  'checkmk_support_contract.html" target="_blank">our website</a>.'
                  ))
            html.close_div()
            html.open_div(id_="fail_msg", style="display:none")
            report_url = makeuri_contextless(
                request,
                [
                    ("subject",
                     "Checkmk Crash Report - " + self._get_version()),
                ],
                filename="mailto:" + self._get_crash_report_target(),
            )
            html.show_error(
                _("Failed to send the crash report. Please download it manually and send it "
                  'to <a href="%s">%s</a>') %
                (report_url, self._get_crash_report_target()))
            html.close_div()
            html.javascript(
                "cmk.transfer.submit_crash_report(%s, %s);" % (json.dumps(
                    config.crash_report_url), json.dumps(url_encoded_params)))
        except MKUserError as e:
            user_errors.add(e)

        return details
Exemple #14
0
def _process_message_message(msg):
    msg["id"] = utils.gen_id()
    msg["time"] = time.time()

    if isinstance(msg["dest"], str):
        dest_what = msg["dest"]
    else:
        dest_what = msg["dest"][0]

    if dest_what == "all_users":
        recipients = list(config.multisite_users.keys())
    elif dest_what == "online":
        recipients = userdb.get_online_user_ids()
    elif dest_what == "list":
        recipients = msg["dest"][1]
    else:
        recipients = []

    num_recipients = len(recipients)

    num_success: Dict[str, int] = {}
    for method in msg["methods"]:
        num_success[method] = 0

    # Now loop all messaging methods to send the messages
    errors: Dict[str, List[Tuple]] = {}
    for user_id in recipients:
        for method in msg["methods"]:
            try:
                handler = _messaging_methods()[method]["handler"]
                handler(user_id, msg)
                num_success[method] = num_success[method] + 1
            except MKInternalError as e:
                errors.setdefault(method, []).append((user_id, e))

    message = escape_html_permissive(
        _("The message has successfully been sent..."))
    message += html.render_br()

    parts = []
    for method in msg["methods"]:
        parts.append(
            html.render_li(
                _messaging_methods()[method]["confirmation_title"] +
                (_(" for all recipients.") if num_success[method] ==
                 num_recipients else _(" for %d of %d recipients.") %
                 (num_success[method], num_recipients))))

    message += html.render_ul(HTML().join(parts))
    message += html.render_p(_("Recipients: %s") % ", ".join(recipients))
    html.show_message(message)

    if errors:
        error_message = HTML()
        for method, method_errors in errors.items():
            error_message += _(
                "Failed to send %s messages to the following users:") % method
            table_rows = HTML()
            for user_id, exception in method_errors:
                table_rows += html.render_tr(
                    html.render_td(html.render_tt(user_id)) +
                    html.render_td(str(exception)))
            error_message += html.render_table(table_rows) + html.render_br()
        html.show_error(error_message)
Exemple #15
0
def _process_notify_message(msg):
    msg['id'] = utils.gen_id()
    msg['time'] = time.time()

    # construct the list of recipients
    recipients = []

    if isinstance(msg['dest'], str):
        dest_what = msg['dest']
    else:
        dest_what = msg['dest'][0]

    if dest_what == 'broadcast':
        recipients = config.multisite_users.keys()

    elif dest_what == 'online':
        recipients = userdb.get_online_user_ids()

    elif dest_what == 'list':
        recipients = msg['dest'][1]

    num_recipients = len(recipients)

    num_success = {}
    for method in msg['methods']:
        num_success[method] = 0

    # Now loop all notitification methods to send the notifications
    errors = {}
    for user_id in recipients:
        for method in msg['methods']:
            try:
                handler = _notify_methods()[method]['handler']
                handler(user_id, msg)
                num_success[method] = num_success[method] + 1
            except MKInternalError as e:
                errors.setdefault(method, []).append((user_id, e))

    message = _('The notification has been sent via<br>')
    message += "<table>"
    for method in msg['methods']:
        message += "<tr><td>%s</td><td>to %d of %d recipients</td></tr>" %\
                        (_notify_methods()[method]["title"], num_success[method], num_recipients)
    message += "</table>"

    message += _('<p>Sent notification to: %s</p>') % ', '.join(recipients)
    message += '<a href="%s">%s</a>' % (html.makeuri(
        []), _('Back to previous page'))
    html.show_message(HTML(message))

    if errors:
        error_message = ""
        for method, method_errors in errors.items():
            error_message += _(
                "Failed to send %s notifications to the following users:"
            ) % method
            table_rows = ''
            for user, exception in method_errors:
                table_rows += html.render_tr(html.render_td(html.render_tt(user))\
                                             + html.render_td(exception))
            error_message += html.render_table(table_rows) + html.render_br()
        html.show_error(HTML(error_message))
Exemple #16
0
 def page(self):
     html.show_message(_("(This module is not yet implemented)"))
Exemple #17
0
def _wato_page_handler(current_mode: str,
                       mode_permissions: Optional[List[PermissionName]],
                       mode_class: Type[WatoMode]) -> None:
    try:
        init_wato_datastructures(with_wato_lock=not html.is_transaction())
    except Exception:
        # Snapshot must work in any case
        if current_mode == 'snapshot':
            pass
        else:
            raise

    # Check general permission for this mode
    if mode_permissions is not None and not config.user.may("wato.seeall"):
        _ensure_mode_permissions(mode_permissions)

    mode = mode_class()

    # Do actions (might switch mode)
    if html.is_transaction():
        try:
            config.user.need_permission("wato.edit")

            # Even if the user has seen this mode because auf "seeall",
            # he needs an explicit access permission for doing changes:
            if config.user.may("wato.seeall"):
                if mode_permissions:
                    _ensure_mode_permissions(mode_permissions)

            if cmk.gui.watolib.read_only.is_enabled(
            ) and not cmk.gui.watolib.read_only.may_override():
                raise MKUserError(None, cmk.gui.watolib.read_only.message())

            result = mode.action()
            if isinstance(result, (tuple, str, bool)):
                raise MKGeneralException(
                    f"WatoMode \"{current_mode}\" returns unsupported return value: {result!r}"
                )

            # We assume something has been modified and increase the config generation ID by one.
            update_config_generation()

            if config.wato_use_git:
                do_git_commit()

            # Handle two cases:
            # a) Don't render the page content after action
            #    (a confirm dialog is displayed by the action, or a non-HTML content was sent)
            # b) Redirect to another page
            if isinstance(result, FinalizeRequest):
                raise result

        except MKUserError as e:
            html.add_user_error(e.varname, str(e))

        except MKAuthException as e:
            reason = e.args[0]
            html.add_user_error(None, reason)

    breadcrumb = make_main_menu_breadcrumb(
        mode.main_menu()) + mode.breadcrumb()
    page_menu = mode.page_menu(breadcrumb)
    wato_html_head(title=mode.title(),
                   breadcrumb=breadcrumb,
                   page_menu=page_menu,
                   show_body_start=display_options.enabled(display_options.H),
                   show_top_heading=display_options.enabled(display_options.T))

    if not html.is_transaction() or (cmk.gui.watolib.read_only.is_enabled() and
                                     cmk.gui.watolib.read_only.may_override()):
        _show_read_only_warning()

    # Show outcome of failed action on this page
    if html.has_user_errors():
        html.show_user_errors()

    # Show outcome of previous page (that redirected to this one)
    for message in get_flashed_messages():
        html.show_message(message)

    # Show content
    mode.handle_page()

    if is_sidebar_reload_needed():
        html.reload_whole_page()

    wato_html_footer(show_body_end=display_options.enabled(display_options.H))
Exemple #18
0
    def _show_login_page(self) -> None:
        html.set_render_headfoot(False)
        html.add_body_css_class("login")
        html.header(get_page_heading(), Breadcrumb(), javascripts=[])

        default_origtarget = ("index.py" if requested_file_name(request)
                              in ["login", "logout"] else makeuri(request, []))
        origtarget = request.get_url_input("_origtarget", default_origtarget)

        # Never allow the login page to be opened in the iframe. Redirect top page to login page.
        # This will result in a full screen login page.
        html.javascript("""if(top != self) {
    window.top.location.href = location;
}""")

        # When someone calls the login page directly and is already authed redirect to main page
        if requested_file_name(request) == "login" and _check_auth(request):
            raise HTTPRedirect(origtarget)

        html.open_div(id_="login")

        html.open_div(id_="login_window")

        html.open_a(href="https://checkmk.com")
        html.img(
            src=theme.detect_icon_path(icon_name="logo", prefix="mk-"),
            id_="logo",
            class_="custom" if theme.has_custom_logo() else None,
        )
        html.close_a()

        html.begin_form("login",
                        method="POST",
                        add_transid=False,
                        action="login.py")
        html.hidden_field("_login", "1")
        html.hidden_field("_origtarget", origtarget)
        html.label("%s:" % _("Username"),
                   id_="label_user",
                   class_=["legend"],
                   for_="_username")
        html.br()
        html.text_input("_username", id_="input_user")
        html.label("%s:" % _("Password"),
                   id_="label_pass",
                   class_=["legend"],
                   for_="_password")
        html.br()
        html.password_input("_password", id_="input_pass", size=None)

        if user_errors:
            html.open_div(id_="login_error")
            html.show_user_errors()
            html.close_div()

        html.open_div(id_="button_text")
        html.button("_login", _("Login"), cssclass="hot")
        html.close_div()
        html.close_div()

        html.open_div(id_="foot")

        if config.login_screen.get("login_message"):
            html.open_div(id_="login_message")
            html.show_message(config.login_screen["login_message"])
            html.close_div()

        footer: List[HTML] = []
        for title, url, target in config.login_screen.get("footer_links", []):
            footer.append(html.render_a(title, href=url, target=target))

        if "hide_version" not in config.login_screen:
            footer.append(escape_html("Version: %s" % cmk_version.__version__))

        footer.append(
            HTML("&copy; %s" % html.render_a(
                "tribe29 GmbH", href="https://tribe29.com", target="_blank")))

        html.write_html(HTML(" - ").join(footer))

        if cmk_version.is_raw_edition():
            html.br()
            html.br()
            html.write_text(
                _('You can use, modify and distribute Check_MK under the terms of the <a href="%s" target="_blank">'
                  "GNU GPL Version 2</a>.") % "https://checkmk.com/gpl.html")

        html.close_div()

        html.set_focus("_username")
        html.hidden_fields()
        html.end_form()
        html.close_div()

        html.footer()
Exemple #19
0
    def _show_master_control_site(
        self,
        site_id: sites.SiteId,
        site_status_info: Dict[sites.SiteId, List],
        items: List[Tuple[str, str]],
    ) -> None:
        site_state = sites.states().get(site_id)

        if not site_state:
            html.show_error(_("Site state is unknown"))
            return

        if site_state["state"] == "dead":
            html.show_error(site_state["exception"])
            return

        if site_state["state"] == "disabled":
            html.show_message(_("Site is disabled"))
            return

        if site_state["state"] == "unknown":
            if site_state.get("exception"):
                html.show_error(site_state["exception"])
            else:
                html.show_error(_("Site state is unknown"))
            return

        is_cmc = site_state["program_version"].startswith("Check_MK ")

        try:
            site_info = site_status_info[site_id]
        except KeyError:
            html.show_error(_("Site state is unknown"))
            return

        html.open_table(class_="master_control")
        for i, (colname, title) in enumerate(items):
            # Do not show event handlers on Checkmk Micro Core
            if is_cmc and title == _("Event handlers"):
                continue

            if not is_cmc and title == _("Alert handlers"):
                continue

            colvalue = site_info[i]
            url = makeactionuri_contextless(
                request,
                transactions,
                [
                    ("site", site_id),
                    ("switch", colname),
                    ("state", "%d" % (1 - colvalue)),
                ],
                filename="switch_master_state.py",
            )
            onclick = (
                "cmk.ajax.get_url('%s', cmk.utils.update_contents, 'snapin_master_control')" % url
            )

            html.open_tr()
            html.td(title, class_="left")
            html.open_td()
            html.toggle_switch(
                enabled=colvalue,
                help_txt=_("Switch '%s' to '%s'") % (title, _("off") if colvalue else _("on")),
                onclick=onclick,
            )
            html.close_td()
            html.close_tr()

        html.close_table()
Exemple #20
0
    def page(self):
        html.open_div(id_="ldap")
        html.open_table()
        html.open_tr()

        html.open_td()
        html.begin_form("connection", method="POST")
        html.prevent_password_auto_completion()
        vs = self._valuespec()
        vs.render_input("connection", self._connection_cfg)
        vs.set_focus("connection")
        html.hidden_fields()
        html.end_form()
        html.close_td()

        html.open_td(style="padding-left:10px;vertical-align:top")
        html.h2(_('Diagnostics'))
        if not html.request.var('_test') or not self._connection_id:
            html.show_message(
                HTML('<p>%s</p><p>%s</p>' % (
                    _('You can verify the single parts of your ldap configuration using this '
                      'dialog. Simply make your configuration in the form on the left side and '
                      'hit the "Save & Test" button to execute the tests. After '
                      'the page reload, you should see the results of the test here.'
                      ),
                    _('If you need help during configuration or experience problems, please refer '
                      'to the <a target="_blank" '
                      'href="https://checkmk.com/checkmk_multisite_ldap_integration.html">'
                      'LDAP Documentation</a>.'))))
        else:
            connection = userdb.get_connection(self._connection_id)
            assert isinstance(connection, LDAPUserConnector)

            for address in connection.servers():
                html.h3("%s: %s" % (_('Server'), address))
                with table_element('test', searchable=False) as table:
                    for title, test_func in self._tests():
                        table.row()
                        try:
                            state, msg = test_func(connection, address)
                        except Exception as e:
                            state = False
                            msg = _('Exception: %s') % html.render_text(
                                "%s" % e)
                            logger.exception("error testing LDAP %s for %s",
                                             title, address)

                        if state:
                            img = html.render_icon("success", _('Success'))
                        else:
                            img = html.render_icon("failed", _("Failed"))

                        table.cell(_("Test"), title)
                        table.cell(_("State"), img)
                        table.cell(_("Details"), msg)

            connection.disconnect()

        html.close_td()
        html.close_tr()
        html.close_table()
        html.close_div()
Exemple #21
0
    def _end(self) -> None:
        if not self.rows and self.options["omit_if_empty"]:
            return

        if self.options["output_format"] == "csv":
            self._write_csv(csv_separator=request.get_str_input_mandatory(
                "csv_separator", ";"))
            return

        container: ContextManager[bool] = nullcontext(False)
        if self.title:
            if self.options["foldable"] in [
                    Foldable.FOLDABLE_SAVE_STATE,
                    Foldable.FOLDABLE_STATELESS,
            ]:
                html.open_div(class_="foldable_wrapper")
                container = foldable_container(
                    treename="table",
                    id_=self.id,
                    isopen=True,
                    indent=False,
                    title=html.render_h3(self.title,
                                         class_=["treeangle", "title"]),
                    save_state=self.options["foldable"] ==
                    Foldable.FOLDABLE_SAVE_STATE,
                )
            else:
                html.h3(self.title, class_="table")

        with container:
            if self.help:
                html.help(self.help)

            if not self.rows:
                html.div(self.empty_text, class_="info")
                return

            # Controls whether or not actions are available for a table
            rows, actions_visible, search_term = self._evaluate_user_opts()

            # Apply limit after search / sorting etc.
            num_rows_unlimited = len(rows)
            limit = self.limit
            if limit:
                # only use rows up to the limit plus the fixed rows
                limited_rows = []
                for index in range(num_rows_unlimited):
                    row = rows[index]
                    if index < limit or isinstance(row,
                                                   GroupHeader) or row.fixed:
                        limited_rows.append(row)
                # Display corrected number of rows
                num_rows_unlimited -= len([
                    r for r in limited_rows
                    if isinstance(row, GroupHeader) or r.fixed
                ])
                rows = limited_rows

            # Render header
            if self.limit_hint is not None:
                num_rows_unlimited = self.limit_hint

            if limit and num_rows_unlimited > limit:

                html.show_message(
                    _("This table is limited to show only %d of %d rows. "
                      'Click <a href="%s">here</a> to disable the limitation.')
                    % (limit, num_rows_unlimited,
                       makeuri(request, [("limit", "none")])))

            self._write_table(rows, num_rows_unlimited,
                              self._show_action_row(), actions_visible,
                              search_term)

        if self.title and self.options["foldable"] in [
                Foldable.FOLDABLE_SAVE_STATE,
                Foldable.FOLDABLE_STATELESS,
        ]:
            html.close_div()

        return
Exemple #22
0
 def page(self):
     # type: () -> None
     html.show_message(_("(This module is not yet implemented)"))
Exemple #23
0
def _process_notify_message(msg):
    msg["id"] = utils.gen_id()
    msg["time"] = time.time()

    if isinstance(msg["dest"], str):
        dest_what = msg["dest"]
    else:
        dest_what = msg["dest"][0]

    if dest_what == "broadcast":
        recipients = list(config.multisite_users.keys())
    elif dest_what == "online":
        recipients = userdb.get_online_user_ids()
    elif dest_what == "list":
        recipients = msg["dest"][1]
    else:
        recipients = []

    num_recipients = len(recipients)

    num_success = {}
    for method in msg["methods"]:
        num_success[method] = 0

    # Now loop all notitification methods to send the notifications
    errors: Dict[str, List[Tuple]] = {}
    for user_id in recipients:
        for method in msg["methods"]:
            try:
                handler = _notify_methods()[method]["handler"]
                handler(user_id, msg)
                num_success[method] = num_success[method] + 1
            except MKInternalError as e:
                errors.setdefault(method, []).append((user_id, e))

    message = escape_html_permissive(_("The notification has been sent via"))
    message += html.render_br()

    parts = []
    for method in msg["methods"]:
        parts.append(
            html.render_tr(
                html.render_td(_notify_methods()[method]["title"])
                + html.render_td(
                    _("to %d of %d recipients") % (num_success[method], num_recipients)
                )
            )
        )
    message += html.render_table(HTML().join(parts))

    message += html.render_p(_("Sent notification to: %s") % ", ".join(recipients))
    message += html.render_a(_("Back to previous page"), href=makeuri(request, []))
    html.show_message(message)

    if errors:
        error_message = HTML()
        for method, method_errors in errors.items():
            error_message += _("Failed to send %s notifications to the following users:") % method
            table_rows = HTML()
            for user_id, exception in method_errors:
                table_rows += html.render_tr(
                    html.render_td(html.render_tt(user_id)) + html.render_td(exception)
                )
            error_message += html.render_table(table_rows) + html.render_br()
        html.show_error(error_message)
Exemple #24
0
def _wato_page_handler(current_mode: str,
                       mode_permissions: List[PermissionName],
                       mode_class: Type[WatoMode]) -> None:
    try:
        init_wato_datastructures(with_wato_lock=not html.is_transaction())
    except Exception:
        # Snapshot must work in any case
        if current_mode == 'snapshot':
            pass
        else:
            raise

    # Check general permission for this mode
    if mode_permissions is not None and not config.user.may("wato.seeall"):
        _ensure_mode_permissions(mode_permissions)

    mode = mode_class()

    # Do actions (might switch mode)
    action_message: Optional[str] = None
    if html.is_transaction():
        try:
            config.user.need_permission("wato.edit")

            # Even if the user has seen this mode because auf "seeall",
            # he needs an explicit access permission for doing changes:
            if config.user.may("wato.seeall"):
                if mode_permissions:
                    _ensure_mode_permissions(mode_permissions)

            if cmk.gui.watolib.read_only.is_enabled(
            ) and not cmk.gui.watolib.read_only.may_override():
                raise MKUserError(None, cmk.gui.watolib.read_only.message())

            result = mode.action()
            if isinstance(result, tuple):
                newmode, action_message = result
            else:
                newmode = result

            # We assume something has been modified and increase the config generation ID by one.
            update_config_generation()

            # If newmode is False, then we shall immediately abort.
            # This is e.g. the case, if the page outputted non-HTML
            # data, such as a tarball (in the export function). We must
            # be sure not to output *any* further data in that case.
            if newmode is False:
                return

            # if newmode is not None, then the mode has been changed
            if newmode is not None:
                assert not isinstance(newmode, bool)
                if newmode == "":  # no further information: configuration dialog, etc.
                    if action_message:
                        html.show_message(action_message)
                        wato_html_footer()
                    return
                mode_permissions, mode_class = _get_mode_permission_and_class(
                    newmode)
                current_mode = newmode
                mode = mode_class()
                html.request.set_var("mode",
                                     newmode)  # will be used by makeuri

                # Check general permissions for the new mode
                if mode_permissions is not None and not config.user.may(
                        "wato.seeall"):
                    for pname in mode_permissions:
                        if '.' not in pname:
                            pname = "wato." + pname
                        config.user.need_permission(pname)

        except MKUserError as e:
            action_message = "%s" % e
            html.add_user_error(e.varname, action_message)

        except MKAuthException as e:
            reason = e.args[0]
            action_message = reason
            html.add_user_error(None, reason)

    breadcrumb = make_main_menu_breadcrumb(
        mode.main_menu()) + mode.breadcrumb()
    page_menu = mode.page_menu(breadcrumb)
    wato_html_head(title=mode.title(),
                   breadcrumb=breadcrumb,
                   page_menu=page_menu,
                   show_body_start=display_options.enabled(display_options.H),
                   show_top_heading=display_options.enabled(display_options.T))

    if not html.is_transaction() or (cmk.gui.watolib.read_only.is_enabled() and
                                     cmk.gui.watolib.read_only.may_override()):
        _show_read_only_warning()

    # Show outcome of action
    if html.has_user_errors():
        html.show_user_errors()
    elif action_message:
        html.show_message(action_message)

    # Show content
    mode.handle_page()

    if is_sidebar_reload_needed():
        html.reload_sidebar()

    if config.wato_use_git and html.is_transaction():
        do_git_commit()

    wato_html_footer(show_footer=display_options.enabled(display_options.Z),
                     show_body_end=display_options.enabled(display_options.H))
Exemple #25
0
    def _show_login_page(self) -> None:
        html.set_render_headfoot(False)
        html.add_body_css_class("login")
        html.header(config.get_page_heading(), Breadcrumb(), javascripts=[])

        default_origtarget = ("index.py" if html.myfile in ["login", "logout"]
                              else makeuri(global_request, []))
        origtarget = html.get_url_input("_origtarget", default_origtarget)

        # Never allow the login page to be opened in the iframe. Redirect top page to login page.
        # This will result in a full screen login page.
        html.javascript('''if(top != self) {
    window.top.location.href = location;
}''')

        # When someone calls the login page directly and is already authed redirect to main page
        if html.myfile == 'login' and _check_auth(html.request):
            raise HTTPRedirect(origtarget)

        html.open_div(id_="login")

        html.open_div(id_="login_window")

        html.div("" if "hide_version" in config.login_screen else
                 cmk_version.__version__,
                 id_="version")

        html.begin_form("login",
                        method='POST',
                        add_transid=False,
                        action='login.py')
        html.hidden_field('_login', '1')
        html.hidden_field('_origtarget', origtarget)
        html.label("%s:" % _('Username'),
                   id_="label_user",
                   class_=["legend"],
                   for_="_username")
        html.br()
        html.text_input("_username", id_="input_user")
        html.label("%s:" % _('Password'),
                   id_="label_pass",
                   class_=["legend"],
                   for_="_password")
        html.br()
        html.password_input("_password", id_="input_pass", size=None)

        if html.has_user_errors():
            html.open_div(id_="login_error")
            html.show_user_errors()
            html.close_div()

        html.open_div(id_="button_text")
        html.button("_login", _('Login'))
        html.close_div()
        html.close_div()

        html.open_div(id_="foot")

        if config.login_screen.get("login_message"):
            html.open_div(id_="login_message")
            html.show_message(config.login_screen["login_message"])
            html.close_div()

        footer: List[Union[HTML, str]] = []
        for title, url, target in config.login_screen.get("footer_links", []):
            footer.append(html.render_a(title, href=url, target=target))

        if "hide_version" not in config.login_screen:
            footer.append("Version: %s" % cmk_version.__version__)

        footer.append("&copy; %s" % html.render_a(
            "tribe29 GmbH", href="https://checkmk.com", target="_blank"))

        html.write(HTML(" - ").join(footer))

        if cmk_version.is_raw_edition():
            html.br()
            html.br()
            html.write(
                _('You can use, modify and distribute Check_MK under the terms of the <a href="%s" target="_blank">'
                  'GNU GPL Version 2</a>.') % "https://checkmk.com/gpl.html")

        html.close_div()

        html.set_focus('_username')
        html.hidden_fields()
        html.end_form()
        html.close_div()

        html.footer()
Exemple #26
0
    def page_edit(cls):
        back_url = html.get_url_input("back", cls.list_url())

        cls.load()
        cls.need_overriding_permission("edit")

        # Three possible modes:
        # "create" -> create completely new page
        # "clone"  -> like new, but prefill form with values from existing page
        # "edit"   -> edit existing page
        mode = html.request.var('mode', 'edit')
        if mode == "create":
            title = cls.phrase("create")
            page_dict = {
                "name": cls.default_name(),
                "topic": cls.default_topic(),
            }
        else:
            # Load existing page. visual from disk - and create a copy if 'load_user' is set
            page_name = html.request.var("load_name")
            if mode == "edit":
                title = cls.phrase("edit")

                owner_user_id = UserId(
                    html.request.get_unicode_input_mandatory("owner", config.user.id))
                if owner_user_id == config.user.id:
                    page = cls.find_my_page(page_name)
                else:
                    page = cls.find_foreign_page(owner_user_id, page_name)

                if page is None:
                    raise MKUserError(None,
                                      _("The requested %s does not exist") % cls.phrase("title"))

                # TODO FIXME: Looks like a hack
                cls.remove_instance((owner_user_id, page_name))  # will be added later again
            else:  # clone
                title = cls.phrase("clone")
                load_user = html.request.get_unicode_input(
                    "load_user")  # FIXME: Change varname to "owner"

                try:
                    page = cls.instance((load_user, page_name))
                except KeyError:
                    raise MKUserError(None,
                                      _("The requested %s does not exist") % cls.phrase("title"))
            page_dict = page.internal_representation()

        html.header(title)
        html.begin_context_buttons()
        html.context_button(_("Back"), back_url, "back")
        html.end_context_buttons()

        parameters, keys_by_topic = cls._collect_parameters(mode)
        vs = Dictionary(
            title=_("General Properties"),
            render='form',
            optional_keys=False,
            elements=parameters,
            headers=keys_by_topic,
        )

        def validate(page_dict):
            owner_user_id = UserId(html.request.get_unicode_input_mandatory(
                "owner", config.user.id))
            page_name = page_dict["name"]
            if owner_user_id == config.user.id:
                page = cls.find_my_page(page_name)
            else:
                page = cls.find_foreign_page(owner_user_id, page_name)
            if page:
                raise MKUserError(
                    "_p_name",
                    _("You already have an element with the ID <b>%s</b>") % page_dict["name"])

        new_page_dict = forms.edit_valuespec(vs,
                                             page_dict,
                                             validate=validate,
                                             focus="_p_title",
                                             method="POST")
        if new_page_dict is not None:
            # Take over keys from previous value that are specific to the page type
            # and not edited here.
            if mode in ("edit", "clone"):
                for key, value in page_dict.items():
                    new_page_dict.setdefault(key, value)

            owner = UserId(html.request.get_unicode_input_mandatory("owner", config.user.id))
            new_page_dict["owner"] = owner
            new_page = cls(new_page_dict)

            cls.add_page(new_page)
            cls.save_user_instances(owner)
            if mode == "create":
                redirect_url = new_page.after_create_url() or back_url
            else:
                redirect_url = back_url

            html.immediate_browser_redirect(0.5, redirect_url)
            html.show_message(_('Your changes haven been saved.'))
            # Reload sidebar.TODO: This code logically belongs to PageRenderer. How
            # can we simply move it there?
            # TODO: This is not true for all cases. e.g. the BookmarkList is not
            # of type PageRenderer but has a dedicated sidebar snapin. Maybe
            # the best option would be to make a dedicated method to decide whether
            # or not to reload the sidebar.
            if new_page_dict.get("hidden") in [ None, False ] \
               or new_page_dict.get("hidden") != page_dict.get("hidden"):
                html.reload_sidebar()

        else:
            html.show_localization_hint()

        html.footer()
        return
Exemple #27
0
    def _end(self) -> None:
        if not self.rows and self.options["omit_if_empty"]:
            return

        if self.options["output_format"] == "csv":
            self._write_csv(csv_separator=html.request.get_str_input_mandatory(
                "csv_separator", ";"))
            return

        if self.title:
            if self.options["foldable"]:
                html.begin_foldable_container(
                    treename="table",
                    id_=self.id,
                    isopen=True,
                    indent=False,
                    title=html.render_h3(self.title,
                                         class_=["treeangle", "title"]))
            else:
                html.open_h3()
                html.write(self.title)
                html.close_h3()

        if self.help:
            html.help(self.help)

        if not self.rows:
            html.div(self.empty_text, class_="info")
            return

        # Controls whether or not actions are available for a table
        rows, actions_visible, search_term = self._evaluate_user_opts()

        # Apply limit after search / sorting etc.
        num_rows_unlimited = len(rows)
        limit = self.limit
        if limit is not None:
            # only use rows up to the limit plus the fixed rows
            limited_rows = []
            for index in range(num_rows_unlimited):
                row = rows[index]
                if index < limit or isinstance(row, GroupHeader) or row.fixed:
                    limited_rows.append(row)
            # Display corrected number of rows
            num_rows_unlimited -= len([
                r for r in limited_rows
                if isinstance(row, GroupHeader) or r.fixed
            ])
            rows = limited_rows

        # Render header
        if self.limit_hint is not None:
            num_rows_unlimited = self.limit_hint
        self._write_table(rows, num_rows_unlimited, self._show_action_row(),
                          actions_visible, search_term)

        if self.title and self.options["foldable"]:
            html.end_foldable_container()

        if limit is not None and num_rows_unlimited > limit:

            html.show_message(
                _('This table is limited to show only %d of %d rows. '
                  'Click <a href="%s">here</a> to disable the limitation.') %
                (limit, num_rows_unlimited, html.makeuri([('limit', 'none')])))

        return
Exemple #28
0
 def _activation_msg(self):
     html.open_div(id_="async_progress_msg")
     html.show_message(self._get_initial_message())
     html.close_div()
 def _activation_msg(self):
     html.open_div(id_="async_progress_msg", style="display:none")
     html.show_message("")
     html.close_div()
Exemple #30
0
def show_file(site, host_name, file_name):
    int_filename = form_file_to_int(file_name)

    title = _("Logfiles of Host %s: %s") % (host_name, int_filename)
    breadcrumb = _show_file_breadcrumb(host_name, title)
    html.header(
        title, breadcrumb,
        _show_file_page_menu(breadcrumb, site, host_name, int_filename))

    if request.has_var("_ack") and not request.var("_do_actions") == _("No"):
        do_log_ack(site, host_name, file_name)
        return

    try:
        log_chunks = parse_file(site,
                                host_name,
                                int_filename,
                                hidecontext=request.var("_hidecontext",
                                                        "no") == "yes")
    except Exception as e:
        if config.debug:
            raise
        html.show_error(_("Unable to show logfile: <b>%s</b>") % e)
        html.footer()
        return

    if log_chunks is None:
        html.show_error(_("The logfile does not exist on site."))
        html.footer()
        return

    if log_chunks == []:
        html.show_message(
            _("This logfile contains no unacknowledged messages."))
        html.footer()
        return

    html.open_div(id_="logwatch")
    for log in log_chunks:
        html.open_table(class_="groupheader")
        html.open_tr()
        html.td(form_level(log["level"]), class_=form_level(log["level"]))
        html.td(form_datetime(log["datetime"]), class_="date")
        html.close_tr()
        html.close_table()

        html.open_table(class_=["section"])
        for line in log["lines"]:
            html.open_tr(class_=line["class"])
            html.open_td(class_="lines")
            html.icon_button(
                analyse_url(site, host_name, int_filename, line["line"]),
                _("Analyze this line"),
                "analyze",
            )
            html.write_text(line["line"].replace(" ", "&nbsp;").replace(
                "\1", "<br>"))
            html.close_td()
            html.close_tr()

        html.close_table()

    html.close_div()
    html.footer()