def page(self): # Show search form html.begin_form("edit_host", method="POST") html.prevent_password_auto_completion() basic_attributes = [ ( "host_search_host", TextInput(title=_("Hostname", )), "", ), ] html.set_focus("host_search_host") # Attributes configure_attributes( new=False, hosts={}, for_what="host_search", parent=None, varprefix="host_search_", basic_attributes=basic_attributes, ) forms.end() html.hidden_field("host_search", "1") html.hidden_fields() html.end_form()
def _show_form(self) -> None: assert user.id is not None credentials = load_two_factor_credentials(user.id) webauthn_credentials = credentials["webauthn_credentials"] backup_codes = credentials["backup_codes"] html.begin_form("two_factor", method="POST") html.div("", id_="webauthn_message") forms.header(_("Credentials")) forms.section(_("Registered credentials"), simple=True) if webauthn_credentials: self._show_credentials(webauthn_credentials) else: html.i(_("No credentials registered")) forms.section(_("Backup codes"), simple=True) if backup_codes: html.p( _("You have %d unused backup codes left. You can use them as one-time password " "if your key is not available.") % len(backup_codes)) html.i( _("If you regenerate backup codes, you automatically invalidate the existing codes." )) else: html.i(_("No backup codes created yet.")) forms.end() html.hidden_fields() html.end_form() html.footer()
def inpage_search_form(mode: Optional[str] = None, default_value: str = "") -> None: form_name = "inpage_search_form" reset_button_id = "%s_reset" % form_name was_submitted = request.get_ascii_input("filled_in") == form_name html.begin_form(form_name, add_transid=False) html.text_input( "search", size=32, default_value=default_value, placeholder=_("Filter"), required=True, title="", ) html.hidden_fields() if mode: html.hidden_field("mode", mode, add_var=True) reset_url = request.get_ascii_input_mandatory("reset_url", requested_file_with_query(request)) html.hidden_field("reset_url", reset_url, add_var=True) html.button("submit", "", cssclass="submit", help_=_("Apply")) html.buttonlink(reset_url, "", obj_id=reset_button_id, title=_("Reset")) html.end_form() html.javascript( "cmk.page_menu.inpage_search_init(%s, %s)" % (json.dumps(reset_button_id), json.dumps(was_submitted)) )
def _show_form(self) -> None: assert user.id is not None credentials = load_two_factor_credentials(user.id) credential_id = request.get_ascii_input_mandatory("_edit") credential = credentials["webauthn_credentials"].get(credential_id) if credential is None: raise MKUserError("_edit", _("The credential does not exist")) html.begin_form("profile", method="POST") html.prevent_password_auto_completion() html.open_div(class_="wato") self._valuespec(credential).render_input( "profile", { "registered_at": credential["registered_at"], "alias": credential["alias"], }, ) forms.end() html.close_div() html.hidden_field("_edit", credential_id) html.hidden_fields() html.end_form() html.footer()
def _show_start_form(self): html.begin_form("bulkinventory", method="POST") msgs = [] if self._all: vs = vs_bulk_discovery(render_form=True) else: # "Include subfolders" does not make sense for a selection of hosts # which is already given in the following situations: # - in the current folder below 'Selected hosts: Discovery' # - Below 'Bulk import' a automatic service discovery for # imported/selected hosts can be executed vs = vs_bulk_discovery(render_form=True, include_subfolders=False) msgs.append( _("You have selected <b>%d</b> hosts for bulk discovery.") % len(self._get_hosts_to_discover())) # The cast is needed for the moment, because mypy does not understand our data structure here selection = cast(Tuple[bool, bool, bool, bool], self._bulk_discovery_params["selection"]) self._bulk_discovery_params["selection"] = [False] + list( selection[1:]) msgs.append( _("The Checkmk discovery will automatically find and configure services " "to be checked on your hosts and may also discover host labels.") ) html.open_p() html.write_text(" ".join(msgs)) vs.render_input("bulkinventory", self._bulk_discovery_params) forms.end() html.hidden_fields() html.end_form()
def page(self) -> None: host_names = get_hostnames_from_checkboxes() hosts = { host_name: Folder.current().host(host_name) for host_name in host_names } current_host_hash = sha256(repr(hosts).encode()).hexdigest() # When bulk edit has been made with some hosts, then other hosts have been selected # and then another bulk edit has made, the attributes need to be reset before # rendering the form. Otherwise the second edit will have the attributes of the # first set. host_hash = request.var("host_hash") if not host_hash or host_hash != current_host_hash: request.del_vars(prefix="attr_") request.del_vars(prefix="bulk_change_") html.p("%s%s %s" % ( _("You have selected <b>%d</b> hosts for bulk edit. You can now change " "host attributes for all selected hosts at once. ") % len(hosts), _("If a select is set to <i>don't change</i> then currenty not all selected " "hosts share the same setting for this attribute. " "If you leave that selection, all hosts will keep their individual settings." ), _("In case you want to <i>unset</i> attributes on multiple hosts, you need to " "use the <i>bulk cleanup</i> action instead of bulk edit."), )) html.begin_form("edit_host", method="POST") html.prevent_password_auto_completion() html.hidden_field("host_hash", current_host_hash) configure_attributes(False, hosts, "bulk", parent=Folder.current()) forms.end() html.hidden_fields() html.end_form()
def _show_command_form(datasource: ABCDataSource, rows: Rows) -> None: what = datasource.infos[0] html.javascript( """ $(document).ready(function() { $('.command_group').has('x').trigger('expand'); $('x').children().css('background-color', '#f84'); }); """ ) one_shown = False html.open_div(**{"data-role": "collapsible-set"}) for command_class in command_registry.values(): command = command_class() if what in command.tables and user.may(command.permission.name): html.open_div(class_=["command_group"], **{"data-role": "collapsible"}) html.h3(command.title) html.open_p() html.begin_form("actions") html.hidden_field("_do_actions", "yes") html.hidden_field("actions", "yes") command.render(what) html.hidden_fields() html.end_form() html.close_p() html.close_div() one_shown = True html.close_div() if not one_shown: html.write_text(_("No commands are possible in this view"))
def page(self) -> None: html.begin_form("key", method="POST") html.prevent_password_auto_completion() self._vs_key().render_input("key", {}) self._vs_key().set_focus("key") html.hidden_fields() html.end_form()
def page(self): html.begin_form("timeperiod", method="POST") self._valuespec().render_input("timeperiod", self._to_valuespec(self._timeperiod)) forms.end() html.hidden_fields() html.end_form()
def _show_filter_form(show_filters: List[Filter], context: VisualContext) -> None: # Sort filters s = sorted([(f.sort_index, f.title, f) for f in show_filters if f.available()]) html.begin_form("filter") html.open_ul(**{"data-role": "listview", "data-inset": "false"}) for _sort_index, title, f in s: html.open_li(**{"data-role": "fieldcontain"}) html.legend(title) f.display(context.get(f.ident, {})) html.close_li() html.close_ul() html.hidden_fields() html.hidden_field("search", "Search") html.hidden_field("page", "data") html.form_has_submit_button = True # a.results_button functions as a submit button html.end_form() html.final_javascript( """ const filter_form = document.getElementById("form_filter"); const results_button = document.getElementsByClassName("results_button")[0]; cmk.forms.enable_select2_dropdowns(filter_form); results_button.onclick = function(event) { event.preventDefault(); filter_form.submit(); }; """ )
def page(self) -> None: html.p( _("Here you can add icons, for example to use them in bookmarks or " "in custom actions of views. Allowed are single PNG image files " "with a maximum size of 80x80 px. Custom actions have to be defined " "in the global settings and can be used in the custom icons rules " "of hosts and services.")) html.begin_form("upload_form", method="POST") self._vs_upload().render_input("_upload_icon", None) html.hidden_fields() html.end_form() icons = sorted(self._load_custom_icons().items()) with table_element("icons", _("Custom Icons")) as table: for icon_name, category_name in icons: table.row() table.cell(_("Actions"), css=["buttons"]) delete_url = make_confirm_link( url=make_action_link([("mode", "icons"), ("_delete", icon_name)]), message=_( "Do you really want to delete the icon <b>%s</b>?") % icon_name, ) html.icon_button(delete_url, _("Delete this Icon"), "delete") table.cell(_("Icon"), html.render_icon(icon_name), css=["buttons"]) table.cell(_("Name"), icon_name) table.cell(_("Category"), IconSelector.category_alias(category_name))
def _preview_form(self) -> None: if self._params is not None: params = self._params else: params = self._vs_parse_params().default_value() self._vs_parse_params().render_input("_preview", params) html.hidden_fields()
def page(self) -> None: is_configured = self._is_configured() is_configured_globally = self._varname in self._global_settings default_values = ABCConfigDomain.get_all_default_globals() defvalue = default_values[self._varname] value = self._current_settings.get( self._varname, self._global_settings.get(self._varname, defvalue)) hint = self._config_variable.hint() if hint: html.show_warning(hint) html.begin_form("value_editor", method="POST") title = self._valuespec.title() assert isinstance(title, str) forms.header(title) if not active_config.wato_hide_varnames: forms.section(_("Configuration variable:")) html.tt(self._varname) forms.section(_("Current setting")) self._valuespec.render_input("ve", value) self._valuespec.set_focus("ve") html.help(self._valuespec.help()) if is_configured_globally: self._show_global_setting() forms.section(_("Factory setting")) html.write_text(self._valuespec.value_to_html(defvalue)) forms.section(_("Current state")) if is_configured_globally: html.write_text( _('This variable is configured in <a href="%s">global settings</a>.' ) % ("wato.py?mode=edit_configvar&varname=%s" % self._varname)) elif not is_configured: html.write_text(_("This variable is at factory settings.")) else: curvalue = self._current_settings[self._varname] if is_configured_globally and curvalue == self._global_settings[ self._varname]: html.write_text( _("Site setting and global setting are identical.")) elif curvalue == defvalue: html.write_text( _("Your setting and factory settings are identical.")) else: html.write_text(self._valuespec.value_to_html(curvalue)) forms.end() html.hidden_fields() html.end_form()
def page(self): html.begin_form("aux_tag") self._valuespec().render_input("aux_tag", self._aux_tag.get_dict_format()) forms.end() html.show_localization_hint() html.hidden_fields() html.end_form()
def page(self): html.p( _("The WATO configuration can be set to read only mode for all users that are not " "permitted to ignore the read only mode. All users that are permitted to set the " "read only can disable it again when another permitted user enabled it before." )) html.begin_form("read_only", method="POST") self._vs().render_input("_read_only", self._settings) html.hidden_fields() html.end_form()
def page(self): html.begin_form("tag_group", method="POST") self._valuespec().render_input("tag_group", self._tag_group.get_dict_format()) forms.end() html.show_localization_hint() html.hidden_fields() html.end_form()
def _show_import_ical_page(self) -> None: html.p( _("This page can be used to generate a new timeperiod definition based " "on the appointments of an iCalendar (<tt>*.ics</tt>) file. This import is normally used " "to import events like holidays, therefore only single whole day appointments are " "handled by this import.")) html.begin_form("import_ical", method="POST") self._vs_ical().render_input("ical", {}) forms.end() html.hidden_fields() html.end_form()
def page(self) -> None: html.begin_form("edit", method="POST") html.prevent_password_auto_completion() vs = self.valuespec() vs.render_input("_edit", self._entry) vs.set_focus("_edit") forms.end() html.hidden_fields() html.end_form()
def page(self) -> None: job_status_snapshot = self._job.get_status_snapshot() if job_status_snapshot.is_active(): raise HTTPRedirect(self._job.detail_url()) html.begin_form("diagnostics", method="POST") vs_diagnostics = self._vs_diagnostics() vs_diagnostics.render_input("diagnostics", {}) html.hidden_fields() html.end_form()
def page(self): html.open_div(class_="diag_host") html.open_table() html.open_tr() html.open_td() html.begin_form("diag_host", method="POST") html.prevent_password_auto_completion() forms.header(_("Host Properties")) forms.section(legend=False) # The diagnose page shows both snmp variants at the same time # We need to analyse the preconfigured community and set either the # snmp_community or the snmp_v3_credentials vs_dict = {} for key, value in self._host.attributes().items(): if key == "snmp_community" and isinstance(value, tuple): vs_dict["snmp_v3_credentials"] = value continue vs_dict[key] = value vs_host = self._vs_host() vs_host.render_input("vs_host", vs_dict) html.help(vs_host.help()) forms.end() html.open_div(style="margin-bottom:10px") html.close_div() forms.header(_("Options")) value = {} forms.section(legend=False) vs_rules = self._vs_rules() vs_rules.render_input("vs_rules", value) html.help(vs_rules.help()) forms.end() # When clicking "Save & Test" on the "Edit host" page, this will be set # to immediately execute the tests using the just saved settings if request.has_var("_start_on_load"): html.final_javascript("cmk.page_menu.form_submit('diag_host', '_save');") html.hidden_fields() html.end_form() html.close_td() html.open_td(style="padding-left:10px;") self._show_diagnose_output()
def _upload_form(self) -> None: html.begin_form("upload", method="POST") html.p( _( "Using this page you can import several hosts at once into the choosen folder. You can " "choose a CSV file from your workstation to be uploaded, paste a CSV files contents " "into the textarea or simply enter a list of hostnames (one per line) to the textarea." ) ) self._vs_upload().render_input("_upload", None) html.hidden_fields() html.end_form()
def _activation_form(self): if not user.may("wato.activate"): html.show_warning( _("You are not permitted to activate configuration changes.")) return if not self._changes: return if not user.may("wato.activateforeign" ) and self._has_foreign_changes_on_any_site(): html.show_warning( _("Sorry, you are not allowed to activate changes of other users." )) return valuespec = _vs_activation(self.title(), self.has_foreign_changes()) html.begin_form("activate", method="POST", action="") html.hidden_field("activate_until", self._get_last_change_id(), id_="activate_until") if valuespec: title = valuespec.title() assert title is not None forms.header(title) valuespec.render_input("activate", self._value) valuespec.set_focus("activate") html.help(valuespec.help()) if self.has_foreign_changes(): if user.may("wato.activateforeign"): html.show_warning( _("There are some changes made by your colleagues that you will " "activate if you proceed. You need to enable the checkbox above " "to confirm the activation of these changes.")) else: html.show_warning( _("There are some changes made by your colleagues that you can not " "activate because you are not permitted to. You can only activate " "the changes on the sites that are not affected by these changes. " "<br>" "If you need to activate your changes on all sites, please contact " "a permitted user to do it for you.")) forms.end() html.hidden_field("selection_id", weblib.selection_id()) html.hidden_fields() html.end_form() init_rowselect(self.name())
def _show_report_form(self, crash_info: CrashInfo, details: ReportSubmitDetails) -> None: if crash_info["crash_type"] == "gui": self._add_gui_user_infos_to_details(details) html.begin_form("report", method="GET") html.show_user_errors() vs = self._vs_crash_report() vs.render_input("_report", details) vs.set_focus("report") forms.end() html.button("_report", _("Submit Report")) html.hidden_fields() html.end_form()
def page(self): hosts = get_hosts_from_checkboxes() html.p( _("You have selected <b>%d</b> hosts for bulk cleanup. This means removing " "explicit attribute values from hosts. The hosts will then inherit attributes " "configured at the host list or folders or simply fall back to the builtin " "default values.") % len(hosts)) html.begin_form("bulkcleanup", method="POST") forms.header(_("Attributes to remove from hosts")) self._select_attributes_for_bulk_cleanup(hosts) html.hidden_fields() html.end_form()
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, is_required=True) 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>", is_required=True) 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_text(dict(custom_attr_types())[self._attr.get("type")]) self._add_extra_form_sections() self._show_in_table_option() 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.hidden_fields() html.end_form()
def search_form( title: Optional[str] = None, mode: Optional[str] = None, default_value: str = "" ) -> None: html.begin_form("search", add_transid=False) if title: html.write_text(title + " ") html.text_input("search", size=32, default_value=default_value) html.hidden_fields() if mode: html.hidden_field("mode", mode, add_var=True) html.set_focus("search") html.write_text(" ") html.button("_do_seach", _("Search")) html.end_form()
def page(self) -> None: html.p( _( "To be able to download the key, you need to unlock the key by entering the " "passphrase. This is only done to verify that you are allowed to download the key. " "The key will be downloaded in encrypted form." ) ) html.begin_form("key", method="POST") html.prevent_password_auto_completion() self._vs_key().render_input("key", {}) self._vs_key().set_focus("key") html.hidden_fields() html.end_form()
def show_create_view_dialog(next_url=None): vs_ds = DatasourceSelection() ds = "services" # Default selection title = _("Create view") breadcrumb = visuals.visual_page_breadcrumb("views", title, "create") make_header( html, title, breadcrumb, make_simple_form_page_menu( _("View"), breadcrumb, form_name="create_view", button_name="_save", save_title=_("Continue"), ), ) if request.var("_save") and transactions.check_transaction(): try: ds = vs_ds.from_html_vars("ds") vs_ds.validate_value(ds, "ds") if not next_url: next_url = makeuri( request, [("datasource", ds)], filename="create_view_infos.py", ) else: next_url = next_url + "&datasource=%s" % ds raise HTTPRedirect(next_url) except MKUserError as e: html.user_error(e) html.begin_form("create_view") html.hidden_field("mode", "create") forms.header(_("Select Datasource")) forms.section(vs_ds.title()) vs_ds.render_input("ds", ds) html.help(vs_ds.help()) forms.end() html.hidden_fields() html.end_form() html.footer()
def _show_form(self) -> None: assert user.id is not None users = userdb.load_users() user_spec: Optional[UserSpec] = users.get(user.id) if user_spec is None: html.show_warning(_("Sorry, your user account does not exist.")) html.footer() return html.begin_form("profile", method="POST") html.prevent_password_auto_completion() html.open_div(class_="wato") forms.header(_("Personal settings")) forms.section(_("Username"), simple=True) html.write_text(user_spec.get("user_id", user.id)) forms.section(_("Full name"), simple=True) html.write_text(user_spec.get("alias", "")) select_language(user_spec) # Let the user configure how he wants to be notified rulebased_notifications = rulebased_notifications_enabled() if (not rulebased_notifications and user.may("general.edit_notifications") and user_spec.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.")) get_vs_flexible_notifications().render_input( "notification_method", user_spec.get("notification_method")) if user.may("general.edit_user_attributes"): custom_user_attr_topics = get_user_attributes_by_topic() _show_custom_user_attr(user_spec, custom_user_attr_topics.get("personal", [])) forms.header(_("User interface settings")) _show_custom_user_attr( user_spec, custom_user_attr_topics.get("interface", [])) forms.end() html.close_div() html.hidden_fields() html.end_form() html.footer()
def page(self): html.begin_form("random") forms.header(_("Add random hosts")) forms.section(_("Number to create")) html.write_text("%s: " % _("Hosts to create in each folder")) html.text_input("count", default_value="10", cssclass="number") html.set_focus("count") html.br() html.write_text("%s: " % _("Number of folders to create in each level")) html.text_input("folders", default_value="10", cssclass="number") html.br() html.write_text("%s: " % _("Levels of folders to create")) html.text_input("levels", default_value="1", cssclass="number") forms.end() html.hidden_fields() html.end_form()