Esempio n. 1
0
 def render_input(self, varprefix, value):
     html.dropdown(varprefix + "attr_" + self.name(), self._enumlist, value)
Esempio n. 2
0
    def page(self):
        search = get_search_expression()
        search_form(_("Search for permissions: "), "edit_role")

        html.begin_form("role", method="POST")

        # ID
        forms.header(_("Basic Properties"))
        forms.section(_("Internal ID"), simple="builtin" in self._role)
        if self._role.get("builtin"):
            html.write_text("%s (%s)" % (self._role_id, _("builtin role")))
            html.hidden_field("id", self._role_id)
        else:
            html.text_input("id", self._role_id)
            html.set_focus("id")

        # Alias
        forms.section(_("Alias"))
        html.help(_("An alias or description of the role"))
        html.text_input("alias", self._role.get("alias", ""), size=50)

        # Based on
        if not self._role.get("builtin"):
            forms.section(_("Based on role"))
            html.help(
                _("Each user defined role is based on one of the builtin roles. "
                  "When created it will start with all permissions of that role. When due to a software "
                  "update or installation of an addons new permissions appear, the user role will get or "
                  "not get those new permissions based on the default settings of the builtin role it's "
                  "based on."))
            choices = [(i, r["alias"]) for i, r in self._roles.items() if r.get("builtin")]
            html.dropdown("basedon", choices, deflt=self._role.get("basedon", "user"), ordered=True)

        forms.end()

        html.h2(_("Permissions"))

        # Permissions
        base_role_id = self._role.get("basedon", self._role_id)

        html.help(
            _("When you leave the permissions at "default" then they get their "
              "settings from the factory defaults (for builtin roles) or from the "
              "factory default of their base role (for user define roles). Factory defaults "
              "may change due to software updates. When choosing another base role, all "
              "permissions that are on default will reflect the new base role."))

        for section in permission_section_registry.get_sorted_sections():
            # Now filter by the optional search term
            filtered_perms = []
            for perm in permission_registry.get_sorted_permissions(section):
                if search and (search not in perm.title.lower() and
                               search not in perm.name.lower()):
                    continue

                filtered_perms.append(perm)

            if not filtered_perms:
                continue

            forms.header(section.title, isopen=search is not None)
            for perm in filtered_perms:
                forms.section(perm.title)

                pvalue = self._role["permissions"].get(perm.name)
                def_value = base_role_id in perm.defaults

                choices = [("yes", _("yes")), ("no", _("no")),
                           ("default", _("default (%s)") % (def_value and _("yes") or _("no")))]
                deflt = {True: "yes", False: "no"}.get(pvalue, "default")

                html.dropdown("perm_" + perm.name, choices, deflt=deflt, style="width: 130px;")
                html.help(perm.description)

        forms.end()
        html.button("save", _("Save"))
        html.hidden_fields()
        html.end_form()
Esempio n. 3
0
    def page(self):
        # Let exceptions from loading notification scripts happen now
        watolib.load_notification_scripts()

        html.begin_form("user", method="POST")
        html.prevent_password_auto_completion()

        forms.header(_("Identity"))

        # ID
        forms.section(_("Username"), simple=not self._is_new_user)
        if self._is_new_user:
            vs_user_id = UserID(allow_empty=False)

        else:
            vs_user_id = FixedValue(self._user_id)
        vs_user_id.render_input("user_id", self._user_id)

        def lockable_input(name, dflt):
            if not self._is_locked(name):
                html.text_input(name, self._user.get(name, dflt), size=50)
            else:
                html.write_text(self._user.get(name, dflt))
                html.hidden_field(name, self._user.get(name, dflt))

        # Full name
        forms.section(_("Full name"))
        lockable_input('alias', self._user_id)
        html.help(_("Full name or alias of the user"))

        # Email address
        forms.section(_("Email address"))
        email = self._user.get("email", "")
        if not self._is_locked("email"):
            EmailAddress().render_input("email", email)
        else:
            html.write_text(email)
            html.hidden_field("email", email)

        html.help(
            _("The email address is optional and is needed "
              "if the user is a monitoring contact and receives notifications "
              "via Email."))

        forms.section(_("Pager address"))
        lockable_input('pager', '')
        html.help(_("The pager address is optional "))

        if cmk_version.is_managed_edition():
            forms.section(self._vs_customer.title())
            self._vs_customer.render_input("customer",
                                           managed.get_customer_id(self._user))

            html.help(self._vs_customer.help())

        vs_sites = self._vs_sites()
        forms.section(vs_sites.title())
        authorized_sites = self._user.get("authorized_sites",
                                          vs_sites.default_value())
        if not self._is_locked("authorized_sites"):
            vs_sites.render_input("authorized_sites", authorized_sites)
        else:
            html.write_html(vs_sites.value_to_text(authorized_sites))
        html.help(vs_sites.help())

        self._show_custom_user_attributes('ident')

        forms.header(_("Security"))
        forms.section(_("Authentication"))

        is_automation = self._user.get("automation_secret", None) is not None
        html.radiobutton("authmethod", "password", not is_automation,
                         _("Normal user login with password"))
        html.open_ul()
        html.open_table()
        html.open_tr()
        html.td(_("password:"******"_password_" + self._pw_suffix(),
                                autocomplete="new-password")
            html.close_td()
            html.close_tr()

            html.open_tr()
            html.td(_("repeat:"))
            html.open_td()
            html.password_input("_password2_" + self._pw_suffix(),
                                autocomplete="new-password")
            html.write_text(" (%s)" % _("optional"))
            html.close_td()
            html.close_tr()

            html.open_tr()
            html.td("%s:" % _("Enforce change"))
            html.open_td()
            # Only make password enforcement selection possible when user is allowed to change the PW
            uid = None if self._user_id is None else UserId(self._user_id)
            if (self._is_new_user
                    or (config.user_may(uid, 'general.edit_profile')
                        and config.user_may(uid, 'general.change_password'))):
                html.checkbox(
                    "enforce_pw_change",
                    self._user.get("enforce_pw_change", False),
                    label=_("Change password at next login or access"))
            else:
                html.write_text(
                    _("Not permitted to change the password. Change can not be enforced."
                      ))
        else:
            html.i(
                _('The password can not be changed (It is locked by the user connector).'
                  ))
            html.hidden_field('_password', '')
            html.hidden_field('_password2', '')

        html.close_td()
        html.close_tr()
        html.close_table()
        html.close_ul()

        html.radiobutton("authmethod", "secret", is_automation,
                         _("Automation secret for machine accounts"))

        html.open_ul()
        html.text_input("_auth_secret",
                        self._user.get("automation_secret", ""),
                        size=30,
                        id_="automation_secret")
        html.write_text(" ")
        html.open_b(style=["position: relative", "top: 4px;"])
        html.write("  ")
        html.icon_button(
            "javascript:cmk.wato.randomize_secret('automation_secret', 20);",
            _("Create random secret"), "random")
        html.close_b()
        html.close_ul()

        html.help(
            _("If you want the user to be able to login "
              "then specify a password here. Users without a login make sense "
              "if they are monitoring contacts that are just used for "
              "notifications. The repetition of the password is optional. "
              "<br>For accounts used by automation processes (such as fetching "
              "data from views for further procession), set the method to "
              "<u>secret</u>. The secret will be stored in a local file. Processes "
              "with read access to that file will be able to use Multisite as "
              "a webservice without any further configuration."))

        # Locking
        forms.section(_("Disable password"), simple=True)
        if not self._is_locked('locked'):
            html.checkbox("locked",
                          self._user.get("locked", False),
                          label=_("disable the login to this account"))
        else:
            html.write_text(
                _('Login disabled') if self._user.
                get("locked", False) else _('Login possible'))
            html.hidden_field('locked',
                              '1' if self._user.get("locked", False) else '')
        html.help(
            _("Disabling the password will prevent a user from logging in while "
              "retaining the original password. Notifications are not affected "
              "by this setting."))

        forms.section(_("Idle timeout"))
        idle_timeout = self._user.get("idle_timeout")
        if not self._is_locked("idle_timeout"):
            watolib.get_vs_user_idle_timeout().render_input(
                "idle_timeout", idle_timeout)
        else:
            html.write_text(idle_timeout)
            html.hidden_field("idle_timeout", idle_timeout)

        # Roles
        forms.section(_("Roles"))
        is_member_of_at_least_one = False
        for role_id, role in sorted(self._roles.items(),
                                    key=lambda x: (x[1]["alias"], x[0])):
            if not self._is_locked("roles"):
                html.checkbox("role_" + role_id, role_id
                              in self._user.get("roles", []))
                url = watolib.folder_preserving_link([("mode", "edit_role"),
                                                      ("edit", role_id)])
                html.a(role["alias"], href=url)
                html.br()
            else:
                is_member = role_id in self._user.get("roles", [])
                if is_member:
                    is_member_of_at_least_one = True
                    url = watolib.folder_preserving_link([("mode",
                                                           "edit_role"),
                                                          ("edit", role_id)])
                    html.a(role["alias"], href=url)
                    html.br()

                html.hidden_field("role_" + role_id, '1' if is_member else '')
        if self._is_locked('roles') and not is_member_of_at_least_one:
            html.i(_('No roles assigned.'))
        self._show_custom_user_attributes('security')

        # Contact groups
        forms.header(_("Contact Groups"), isopen=False)
        forms.section()
        groups_page_url = watolib.folder_preserving_link([("mode",
                                                           "contact_groups")])
        group_assign_url = watolib.folder_preserving_link([
            ("mode", "rulesets"), ("group", "grouping")
        ])
        if not self._contact_groups:
            html.write(
                _("Please first create some <a href='%s'>contact groups</a>") %
                groups_page_url)
        else:
            entries = sorted([(group['alias'] or c, c)
                              for c, group in self._contact_groups.items()])
            is_member_of_at_least_one = False
            for alias, gid in entries:
                is_member = gid in self._user.get("contactgroups", [])

                if not self._is_locked('contactgroups'):
                    html.checkbox("cg_" + gid, gid
                                  in self._user.get("contactgroups", []))
                else:
                    if is_member:
                        is_member_of_at_least_one = True
                    html.hidden_field("cg_" + gid, '1' if is_member else '')

                if not self._is_locked('contactgroups') or is_member:
                    url = watolib.folder_preserving_link([
                        ("mode", "edit_contact_group"), ("edit", gid)
                    ])
                    html.a(alias, href=url)
                    html.br()

            if self._is_locked(
                    'contactgroups') and not is_member_of_at_least_one:
                html.i(_('No contact groups assigned.'))

        html.help(
            _("Contact groups are used to assign monitoring "
              "objects to users. If you haven't defined any contact groups yet, "
              "then first <a href='%s'>do so</a>. Hosts and services can be "
              "assigned to contact groups using <a href='%s'>rules</a>.<br><br>"
              "If you do not put the user into any contact group "
              "then no monitoring contact will be created for the user.") %
            (groups_page_url, group_assign_url))

        forms.header(_("Notifications"), isopen=False)
        if not self._rbn_enabled():
            forms.section(_("Enabling"), simple=True)
            html.checkbox("notifications_enabled",
                          self._user.get("notifications_enabled", False),
                          label=_("enable notifications"))
            html.help(
                _("Notifications are sent out "
                  "when the status of a host or service changes."))

            # Notification period
            forms.section(_("Notification time period"))
            user_np = self._user.get("notification_period")
            if not isinstance(user_np, str):
                raise Exception("invalid notification period %r" % (user_np, ))
            choices: Choices = [(id_, "%s" % (tp["alias"]))
                                for (id_, tp) in self._timeperiods.items()]
            html.dropdown("notification_period",
                          choices,
                          deflt=user_np,
                          ordered=True)
            html.help(
                _("Only during this time period the "
                  "user will get notifications about host or service alerts."))

            # Notification options
            notification_option_names = {  # defined here: _() must be executed always!
                "host": {
                    "d": _("Host goes down"),
                    "u": _("Host gets unreachble"),
                    "r": _("Host goes up again"),
                },
                "service": {
                    "w": _("Service goes into warning state"),
                    "u": _("Service goes into unknown state"),
                    "c": _("Service goes into critical state"),
                    "r": _("Service recovers to OK"),
                },
                "both": {
                    "f": _("Start or end of flapping state"),
                    "s": _("Start or end of a scheduled downtime"),
                }
            }

            forms.section(_("Notification Options"))
            for title, what, opts in [(_("Host events"), "host", "durfs"),
                                      (_("Service events"), "service",
                                       "wucrfs")]:
                html.write_text("%s:" % title)
                html.open_ul()

                user_opts = self._user.get(what + "_notification_options",
                                           opts)
                for opt in opts:
                    opt_name = notification_option_names[what].get(
                        opt, notification_option_names["both"].get(opt))
                    html.checkbox(what + "_" + opt,
                                  opt in user_opts,
                                  label=opt_name)
                    html.br()
                html.close_ul()

            html.help(
                _("Here you specify which types of alerts "
                  "will be notified to this contact. Note: these settings will only be saved "
                  "and used if the user is member of a contact group."))

            forms.section(_("Notification Method"))
            watolib.get_vs_flexible_notifications().render_input(
                "notification_method", self._user.get("notification_method"))

        else:
            forms.section(_("Fallback notifications"), simple=True)

            html.checkbox("fallback_contact",
                          self._user.get("fallback_contact", False),
                          label=_("Receive fallback notifications"))

            html.help(
                _("In case none of your notification rules handles a certain event a notification "
                  "will be sent to this contact. This makes sure that in that case at least <i>someone</i> "
                  "gets notified. Furthermore this contact will be used for notifications to any host or service "
                  "that is not known to the monitoring. This can happen when you forward notifications "
                  "from the Event Console.<br><br>Notification fallback can also configured in the global "
                  "setting <a href=\"wato.py?mode=edit_configvar&varname=notification_fallback_email\">"
                  "Fallback email address for notifications</a>."))

        self._show_custom_user_attributes('notify')

        forms.header(_("Personal Settings"), isopen=False)
        select_language(self._user)
        self._show_custom_user_attributes('personal')

        # Later we could add custom macros here, which then could be used
        # for notifications. On the other hand, if we implement some check_mk
        # --notify, we could directly access the data in the account with the need
        # to store values in the monitoring core. We'll see what future brings.
        forms.end()
        if self._is_new_user:
            html.set_focus("user_id")
        else:
            html.set_focus("alias")
        html.hidden_fields()
        html.end_form()
Esempio n. 4
0
    def show(self):
        if not watolib.is_wato_slave_site():
            if not config.wato_enabled:
                html.write_text(_("WATO is disabled."))
                return False

        user_folders = compute_foldertree()

        #
        # Render link target selection
        #
        selected_topic, selected_target = config.user.load_file("foldertree",
                                                                (_('Hosts'), 'allhosts'))

        dashboard.load_dashboards()
        topic_views = visuals_by_topic(views.get_permitted_views().items() +
                                       dashboard.permitted_dashboards().items())
        topics = [(t, t) for t, _s in topic_views]

        html.open_table()
        html.open_tr()
        html.td(_('Topic:'), class_="label")
        html.open_td()
        html.dropdown(
            "topic",
            topics,
            deflt=selected_topic,
            onchange='cmk.sidebar.wato_tree_topic_changed(this)')
        html.close_td()
        html.close_tr()

        html.open_tr()
        html.td(_("View:"), class_="label")
        html.open_td()

        for topic, view_list in topic_views:
            targets = []
            for t, title, name, is_view in view_list:
                if config.visible_views and name not in config.visible_views:
                    continue
                if config.hidden_views and name in config.hidden_views:
                    continue
                if t == topic:
                    if not is_view:
                        name = 'dashboard|' + name
                    targets.append((name, title))

            if topic != selected_topic:
                default, style = '', 'display:none'
            else:
                default, style = selected_target, None
            html.dropdown(
                "target_%s" % topic,
                targets,
                deflt=default,
                onchange='cmk.sidebar.wato_tree_target_changed(this)',
                style=style)

        html.close_td()
        html.close_tr()
        html.close_table()

        # Now render the whole tree
        if user_folders:
            render_tree_folder("wato-hosts",
                               user_folders.values()[0], 'cmk.sidebar.wato_tree_click')
Esempio n. 5
0
    def page(self):
        # TODO: remove subclass specific things specifict things (everything with _type == 'user')
        html.begin_form("attr")
        forms.header(_("Properties"))
        forms.section(_("Name"), simple=not self._new)
        html.help(
            _("The name of the attribute is used as an internal key. It cannot be "
              "changed later."))
        if self._new:
            html.text_input("name", self._attr.get('name', ''))
            html.set_focus("name")
        else:
            html.write_text(self._name)
            html.set_focus("title")

        forms.section(_("Title") + "<sup>*</sup>")
        html.help(_("The title is used to label this attribute."))
        html.text_input("title", self._attr.get('title', ''))

        forms.section(_('Topic'))
        html.help(
            _('The attribute is added to this section in the edit dialog.'))
        html.dropdown('topic',
                      self._topics,
                      deflt=self._attr.get('topic', self._default_topic))

        forms.section(_('Help Text') + "<sup>*</sup>")
        html.help(
            _('You might want to add some helpful description for the attribute.'
              ))
        html.text_area('help', self._attr.get('help', ''))

        forms.section(_('Data type'))
        html.help(_('The type of information to be stored in this attribute.'))
        if self._new:
            html.dropdown('type',
                          custom_attr_types(),
                          deflt=self._attr.get('type', ''))
        else:
            html.write(dict(custom_attr_types())[self._attr.get('type')])

        self._add_extra_form_sections()

        forms.section(_('Show in WATO host table'))
        html.help(
            _('This attribute is only visibile on the edit host and folder pages by default, but '
              'you can also make it visible in the host overview tables of WATO.'
              ))
        html.checkbox(
            'show_in_table',
            self._attr.get('show_in_table', False),
            label=_(
                "Show the setting of the attribute in the WATO host list table"
            ))

        forms.section(_('Add to monitoring configuration'))
        html.help(self._macro_help)
        html.checkbox('add_custom_macro',
                      self._attr.get('add_custom_macro', False),
                      label=self._macro_label)

        forms.end()
        html.show_localization_hint()
        html.button("save", _("Save"))
        html.hidden_fields()
        html.end_form()
Esempio n. 6
0
def page_graph():
    host = html.request.get_str_input_mandatory("host")
    service = html.request.get_str_input_mandatory("service")
    dsname = html.request.get_str_input_mandatory("dsname")

    html.header(_("Prediction for %s - %s - %s") % (host, service, dsname))

    # Get current value from perf_data via Livestatus
    current_value = get_current_perfdata(host, service, dsname)

    pred_dir = prediction.predictions_dir(host, service, dsname)
    if not os.path.exists(pred_dir):
        raise MKGeneralException(
            _("There is currently no prediction information "
              "available for this service."))

    # Load all prediction information, sort by time of generation
    tg_name = html.request.var("timegroup")
    timegroup = None
    timegroups: List[prediction.PredictionInfo] = []
    now = time.time()
    for f in os.listdir(pred_dir):
        if not f.endswith(".info"):
            continue
        tg_info = prediction.retrieve_data_for_prediction(
            pred_dir + "/" + f, "<unknown>" if timegroup is None else timegroup)
        if tg_info is None:
            continue

        tg_info["name"] = f[:-5]
        timegroups.append(tg_info)
        if tg_info["name"] == tg_name or (tg_name is None and
                                          (tg_info["range"][0] <= now <= tg_info["range"][1])):
            timegroup = tg_info
            tg_name = tg_info["name"]

    timegroups.sort(key=lambda x: x["range"][0])

    choices = [(tg_info_["name"], tg_info_["name"].title()) for tg_info_ in timegroups]

    if not timegroup:
        if not timegroups:
            raise MKGeneralException(_("Missing prediction information."))
        timegroup = timegroups[0]
        tg_name = choices[0][0]
    if tg_name is None:
        raise Exception("should not happen")

    html.begin_form("prediction")
    html.write(_("Show prediction for "))
    html.dropdown("timegroup", choices, deflt=tg_name, onchange="document.prediction.submit();")
    html.hidden_fields()
    html.end_form()

    # Get prediction data
    path = pred_dir + "/" + timegroup["name"]
    tg_data = prediction.retrieve_data_for_prediction(path, tg_name)
    if tg_data is None:
        raise MKGeneralException(_("Missing prediction data."))

    swapped = swap_and_compute_levels(tg_data, timegroup['params'])
    vertical_range = compute_vertical_range(swapped)
    legend = [
        ("#000000", _("Reference")),
        ("#ffffff", _("OK area")),
        ("#ffff00", _("Warning area")),
        ("#ff0000", _("Critical area")),
    ]
    if current_value is not None:
        legend.append(("#0000ff", _("Current value: %.2f") % current_value))

    create_graph(timegroup["name"], graph_size, timegroup["range"], vertical_range, legend)

    if "levels_upper" in timegroup['params']:
        render_dual_area(swapped["upper_warn"], swapped["upper_crit"], "#fff000", 0.4)
        render_area_reverse(swapped["upper_crit"], "#ff0000", 0.1)

    if "levels_lower" in timegroup['params']:
        render_dual_area(swapped["lower_crit"], swapped["lower_warn"], "#fff000", 0.4)
        render_area(swapped["lower_crit"], "#ff0000", 0.1)

    vscala_low = vertical_range[0]
    vscala_high = vertical_range[1]
    vert_scala = compute_vertical_scala(vscala_low, vscala_high)
    time_scala = [[timegroup["range"][0] + i * 3600, "%02d:00" % i] for i in range(0, 25, 2)]
    render_coordinates(vert_scala, time_scala)

    if "levels_lower" in timegroup['params']:
        render_dual_area(swapped["average"], swapped["lower_warn"], "#ffffff", 0.5)
        render_curve(swapped["lower_warn"], "#e0e000", square=True)
        render_curve(swapped["lower_crit"], "#f0b0a0", square=True)

    if "levels_upper" in timegroup['params']:
        render_dual_area(swapped["upper_warn"], swapped["average"], "#ffffff", 0.5)
        render_curve(swapped["upper_warn"], "#e0e000", square=True)
        render_curve(swapped["upper_crit"], "#f0b0b0", square=True)
    render_curve(swapped["average"], "#000000")
    render_curve(swapped["average"], "#000000")  # repetition makes line bolder

    # Try to get current RRD data and render it also
    from_time, until_time = timegroup["range"]
    now = time.time()
    if from_time <= now <= until_time:
        timeseries = prediction.get_rrd_data(host, service, dsname, "MAX", from_time, until_time)
        rrd_data = timeseries.values

        render_curve(rrd_data, "#0000ff", 2)
        if current_value is not None:
            rel_time = (now - prediction.timezone_at(now)) % timegroup["slice"]
            render_point(timegroup["range"][0] + rel_time, current_value, "#0000ff")

    html.footer()
Esempio n. 7
0
    def render(self, what):
        html.write_text(_('Downtime Comment') + ": ")
        html.text_input("_down_comment", "", size=60, submit="")
        html.hr()
        html.button("_down_from_now", _("From now for"))
        html.nbsp()
        html.text_input("_down_minutes",
                        default_value="60",
                        size=4,
                        submit="_down_from_now",
                        cssclass="number")
        html.write_text("&nbsp; " + _("minutes"))
        html.hr()
        for time_range in config.user_downtime_timeranges:
            html.button("_downrange__%s" % time_range['end'], _u(time_range['title']))
        if what != "aggr" and config.user.may("action.remove_all_downtimes"):
            html.write_text(" &nbsp; - &nbsp;")
            html.button("_down_remove", _("Remove all"))
        html.hr()
        if config.adhoc_downtime and config.adhoc_downtime.get("duration"):
            adhoc_duration = config.adhoc_downtime.get("duration")
            adhoc_comment = config.adhoc_downtime.get("comment", "")
            html.button("_down_adhoc", _("Adhoc for %d minutes") % adhoc_duration)
            html.nbsp()
            html.write_text(_('with comment') + ": ")
            html.write(adhoc_comment)
            html.hr()

        html.button("_down_custom", _("Custom time range"))
        self._vs_down_from().render_input("_down_from", time.time())
        html.write_text("&nbsp; " + _('to') + " &nbsp;")
        self._vs_down_to().render_input("_down_to", time.time() + 7200)
        html.hr()
        html.checkbox("_down_flexible", False, label="%s " % _('flexible with max. duration'))
        self._vs_duration().render_input("_down_duration", 7200)
        if what == "host":
            html.hr()
            html.checkbox("_include_childs", False, label=_('Also set downtime on child hosts'))
            html.write_text("  ")
            html.checkbox("_include_childs_recurse", False, label=_('Do this recursively'))
        elif what == "service":
            html.hr()
            html.checkbox("_on_hosts",
                          False,
                          label=_('Schedule downtimes on the affected '
                                  '<b>hosts</b> instead of on the individual '
                                  'services'))

        if self._has_recurring_downtimes():
            html.hr()
            html.checkbox("_down_do_recur",
                          False,
                          label=_("Repeat this downtime on a regular basis every"))
            html.write_text(" ")

            from cmk.gui.cee.plugins.wato.cmc import recurring_downtimes_types  # pylint: disable=no-name-in-module

            recurring_selections = [
                (str(k), v) for (k, v) in sorted(recurring_downtimes_types().items())
            ]
            html.dropdown("_down_recurring", recurring_selections, deflt="3")
            html.write_text(_("(This only works when using CMC)"))
Esempio n. 8
0
    def _preview(self) -> None:
        html.begin_form("preview", method="POST")
        self._preview_form()

        attributes = self._attribute_choices()

        # first line could be missing in situation of import error
        csv_reader = self._open_csv_file()
        if not csv_reader:
            return  # don't try to show preview when CSV could not be read

        html.h2(_("Preview"))
        attribute_list = "<ul>%s</ul>" % "".join(
            ["<li>%s (%s)</li>" % a for a in attributes if a[0] is not None]
        )
        html.help(
            _(
                "This list shows you the first 10 rows from your CSV file in the way the import is "
                "currently parsing it. If the lines are not splitted correctly or the title line is "
                "not shown as title of the table, you may change the import settings above and try "
                "again."
            )
            + "<br><br>"
            + _(
                "The first row below the titles contains fields to specify which column of the "
                "CSV file should be imported to which attribute of the created hosts. The import "
                "progress is trying to match the columns to attributes automatically by using the "
                "titles found in the title row (if you have some). "
                "If you use the correct titles, the attributes can be mapped automatically. The "
                "currently available attributes are:"
            )
            + attribute_list
            + _(
                "You can change these assignments according to your needs and then start the "
                "import by clicking on the <i>Import</i> button above."
            )
        )

        # Wenn bei einem Host ein Fehler passiert, dann wird die Fehlermeldung zu dem Host angezeigt, so dass man sehen kann, was man anpassen muss.
        # Die problematischen Zeilen sollen angezeigt werden, so dass man diese als Block in ein neues CSV-File eintragen kann und dann diese Datei
        # erneut importieren kann.
        if self._has_title_line:
            try:
                headers = list(next(csv_reader))
            except StopIteration:
                headers = []  # nope, there is no header
        else:
            headers = []

        rows = list(csv_reader)

        # Determine how many columns should be rendered by using the longest column
        num_columns = max([len(r) for r in [headers] + rows])

        with table_element(
            sortable=False, searchable=False, omit_headers=not self._has_title_line
        ) as table:

            # Render attribute selection fields
            table.row()
            for col_num in range(num_columns):
                header = headers[col_num] if len(headers) > col_num else None
                table.cell(escape_html_permissive(header))
                attribute_varname = "attribute_%d" % col_num
                if request.var(attribute_varname):
                    attribute_method = request.get_ascii_input_mandatory(attribute_varname)
                else:
                    attribute_method = self._try_detect_default_attribute(attributes, header)
                    request.del_var(attribute_varname)

                html.dropdown(
                    "attribute_%d" % col_num, attributes, deflt=attribute_method, autocomplete="off"
                )

            # Render sample rows
            for row in rows:
                table.row()
                for cell in row:
                    table.cell(None, cell)

        html.end_form()
Esempio n. 9
0
 def display(self):
     html.dropdown("site", self._choices())
Esempio n. 10
0
def page_graph():
    host = request.get_str_input_mandatory("host")
    service = request.get_str_input_mandatory("service")
    dsname = request.get_str_input_mandatory("dsname")

    breadcrumb = make_service_breadcrumb(host, service)
    html.header(
        _("Prediction for %s - %s - %s") % (host, service, dsname), breadcrumb)

    # Get current value from perf_data via Livestatus
    current_value = get_current_perfdata(host, service, dsname)

    prediction_store = prediction.PredictionStore(host, service, dsname)

    timegroup, choices = _load_prediction_information(
        tg_name=request.var("timegroup"),
        prediction_store=prediction_store,
    )

    html.begin_form("prediction")
    html.write_text(_("Show prediction for "))
    html.dropdown("timegroup",
                  choices,
                  deflt=timegroup.name,
                  onchange="document.prediction.submit();")
    html.hidden_fields()
    html.end_form()

    # Get prediction data
    tg_data = prediction_store.get_data(timegroup.name)
    if tg_data is None:
        raise MKGeneralException(_("Missing prediction data."))

    swapped = swap_and_compute_levels(tg_data, timegroup.params)
    vertical_range = compute_vertical_range(swapped)
    legend = [
        ("#000000", _("Reference")),
        ("#ffffff", _("OK area")),
        ("#ffff00", _("Warning area")),
        ("#ff0000", _("Critical area")),
    ]
    if current_value is not None:
        legend.append(("#0000ff", _("Current value: %.2f") % current_value))

    create_graph(timegroup.name, graph_size, timegroup.range, vertical_range,
                 legend)

    if "levels_upper" in timegroup.params:
        render_dual_area(swapped["upper_warn"], swapped["upper_crit"],
                         "#fff000", 0.4)
        render_area_reverse(swapped["upper_crit"], "#ff0000", 0.1)

    if "levels_lower" in timegroup.params:
        render_dual_area(swapped["lower_crit"], swapped["lower_warn"],
                         "#fff000", 0.4)
        render_area(swapped["lower_crit"], "#ff0000", 0.1)

    vscala_low = vertical_range[0]
    vscala_high = vertical_range[1]
    vert_scala = compute_vertical_scala(vscala_low, vscala_high)
    time_scala = [[timegroup.range[0] + i * 3600,
                   "%02d:00" % i] for i in range(0, 25, 2)]
    render_coordinates(vert_scala, time_scala)

    if "levels_lower" in timegroup.params:
        render_dual_area(swapped["average"], swapped["lower_warn"], "#ffffff",
                         0.5)
        render_curve(swapped["lower_warn"], "#e0e000", square=True)
        render_curve(swapped["lower_crit"], "#f0b0a0", square=True)

    if "levels_upper" in timegroup.params:
        render_dual_area(swapped["upper_warn"], swapped["average"], "#ffffff",
                         0.5)
        render_curve(swapped["upper_warn"], "#e0e000", square=True)
        render_curve(swapped["upper_crit"], "#f0b0b0", square=True)
    render_curve(swapped["average"], "#000000")
    render_curve(swapped["average"], "#000000")  # repetition makes line bolder

    # Try to get current RRD data and render it also
    from_time, until_time = timegroup.range
    now = time.time()
    if from_time <= now <= until_time:
        timeseries = prediction.get_rrd_data(host, service, dsname, "MAX",
                                             from_time, until_time)
        rrd_data = timeseries.values

        render_curve(rrd_data, "#0000ff", 2)
        if current_value is not None:
            rel_time = (now - prediction.timezone_at(now)) % timegroup.slice
            render_point(timegroup.range[0] + rel_time, current_value,
                         "#0000ff")

    html.footer()