def check_mk_remote_automation(site_id, command, args, indata, stdin_data=None, timeout=None, sync=True): site = config.site(site_id) if "secret" not in site: raise MKGeneralException( _("Cannot connect to site \"%s\": The site is not logged in") % site.get("alias", site_id)) if not site.get("replication"): raise MKGeneralException( _("Cannot connect to site \"%s\": The replication is disabled") % site.get("alias", site_id)) if sync: sync_changes_before_remote_automation(site_id) # Now do the actual remote command response = do_remote_automation( config.site(site_id), "checkmk-automation", [ ("automation", command), # The Check_MK automation command ("arguments", mk_repr(args)), # The arguments for the command ("indata", mk_repr(indata)), # The input data ("stdin_data", mk_repr(stdin_data)), # The input data for stdin ("timeout", mk_repr(timeout)), # The timeout ]) return response
def setup_request_fixture(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(automation, "_get_login_secret", lambda **_kwargs: "secret") request.set_var("secret", "secret") request.set_var("command", "checkmk-automation") request.set_var("automation", "test") request.set_var("arguments", mk_repr(None).decode()) request.set_var("indata", mk_repr(None).decode()) request.set_var("stdin_data", mk_repr(None).decode()) request.set_var("timeout", mk_repr(None).decode())
def rule_url(rule: Rule) -> str: return folder_preserving_link([ ("mode", "edit_rule"), ("varname", varname), ("rule_folder", rule.folder.path()), ("rule_id", rule.id), ("host", self._hostname), ( "item", mk_repr(svc_desc_or_item).decode() if svc_desc_or_item else "", ), ("service", mk_repr(svc_desc).decode() if svc_desc else ""), ])
def _legacy_push_user_profile_to_site(site, user_id, profile): url = site["multisiteurl"] + "automation.py?" + urlencode_vars([ ("command", "push-profile"), ("secret", site["secret"]), ("siteid", site['id']), ("debug", config.debug and "1" or ""), ]) response = get_url(url, site.get('insecure', False), data={ 'user_id': user_id, 'profile': mk_repr(profile), }, timeout=60) if not response: raise MKAutomationException(_("Empty output from remote site.")) try: response = mk_eval(response) except Exception: # The remote site will send non-Python data in case of an error. raise MKAutomationException("%s: <pre>%s</pre>" % (_("Got invalid data"), response)) return response
def check_mk_remote_automation_serialized( *, site_id: SiteId, command: str, args: Optional[Sequence[str]], indata: Any, stdin_data: Optional[str] = None, timeout: Optional[int] = None, sync: bool = True, non_blocking_http: bool = False, ) -> SerializedResult: site = get_site_config(site_id) if "secret" not in site: raise MKGeneralException( _('Cannot connect to site "%s": The site is not logged in') % site.get("alias", site_id)) if not site.get("replication"): raise MKGeneralException( _('Cannot connect to site "%s": The replication is disabled') % site.get("alias", site_id)) if sync: sync_changes_before_remote_automation(site_id) if non_blocking_http: # This will start a background job process on the remote site to execute the automation # asynchronously. It then polls the remote site, waiting for completion of the job. return _do_check_mk_remote_automation_in_background_job_serialized( site_id, CheckmkAutomationRequest(command, args, indata, stdin_data, timeout)) # Synchronous execution of the actual remote command in a single blocking HTTP request return SerializedResult( _do_remote_automation_serialized( site=get_site_config(site_id), command="checkmk-automation", vars_=[ ("automation", command), # The Checkmk automation command ("arguments", mk_repr(args)), # The arguments for the command ("indata", mk_repr(indata)), # The input data ("stdin_data", mk_repr(stdin_data)), # The input data for stdin ("timeout", mk_repr(timeout)), # The timeout ], ))
def check_mk_remote_automation(site_id, command, args, indata, stdin_data=None, timeout=None, sync=True, non_blocking_http=False): # type: (SiteId, str, Optional[Sequence[Union[str, Text]]], Any, Optional[str], Optional[int], bool, bool) -> Any site = config.site(site_id) if "secret" not in site: raise MKGeneralException( _("Cannot connect to site \"%s\": The site is not logged in") % site.get("alias", site_id)) if not site.get("replication"): raise MKGeneralException( _("Cannot connect to site \"%s\": The replication is disabled") % site.get("alias", site_id)) if sync: sync_changes_before_remote_automation(site_id) if non_blocking_http: # This will start a background job process on the remote site to execute the automation # asynchronously. It then polls the remote site, waiting for completion of the job. return _do_check_mk_remote_automation_in_background_job( site_id, CheckmkAutomationRequest(command, args, indata, stdin_data, timeout)) # Synchronous execution of the actual remote command in a single blocking HTTP request return do_remote_automation( config.site(site_id), "checkmk-automation", [ ("automation", command), # The Check_MK automation command ("arguments", mk_repr(args)), # The arguments for the command ("indata", mk_repr(indata)), # The input data ("stdin_data", mk_repr(stdin_data)), # The input data for stdin ("timeout", mk_repr(timeout)), # The timeout ])
def _execute_push_profile(self): try: response.set_data( str(watolib_utils.mk_repr(self._automation_push_profile()))) except Exception as e: logger.exception("error pushing profile") if active_config.debug: raise response.set_data( _("Internal automation error: %s\n%s") % (e, traceback.format_exc()))
def _output_analysed_ruleset(self, all_rulesets, rulespec, svc_desc_or_item, svc_desc, known_settings=None): if known_settings is None: known_settings = self._PARAMETERS_UNKNOWN def rule_url(rule: Rule) -> str: return folder_preserving_link([ ("mode", "edit_rule"), ("varname", varname), ("rule_folder", rule.folder.path()), ("rule_id", rule.id), ("host", self._hostname), ( "item", mk_repr(svc_desc_or_item).decode() if svc_desc_or_item else "", ), ("service", mk_repr(svc_desc).decode() if svc_desc else ""), ]) varname = rulespec.name valuespec = rulespec.valuespec url = folder_preserving_link([ ("mode", "edit_ruleset"), ("varname", varname), ("host", self._hostname), ("item", mk_repr(svc_desc_or_item).decode()), ("service", mk_repr(svc_desc).decode()), ]) forms.section(HTMLWriter.render_a(rulespec.title, url)) ruleset = all_rulesets.get(varname) setting, rules = ruleset.analyse_ruleset(self._hostname, svc_desc_or_item, svc_desc) html.open_table(class_="setting") html.open_tr() html.open_td(class_="reason") # Show reason for the determined value if len(rules) == 1: rule_folder, rule_index, rule = rules[0] url = rule_url(rule) html.a(_("Rule %d in %s") % (rule_index + 1, rule_folder.title()), href=rule_url(rule)) elif len(rules) > 1: html.a("%d %s" % (len(rules), _("Rules")), href=url) else: html.span(_("Default value")) html.close_td() # Show the resulting value or factory setting html.open_td( class_=["settingvalue", "used" if len(rules) > 0 else "unused"]) if isinstance(known_settings, dict) and "tp_computed_params" in known_settings: computed_at = known_settings["tp_computed_params"]["computed_at"] html.write_text( _("Timespecific parameters computed at %s") % cmk.utils.render.date_and_time(computed_at)) html.br() known_settings = known_settings["tp_computed_params"]["params"] # In some cases we now the settings from a check_mk automation if known_settings is self._PARAMETERS_OMIT: return # Special handling for logwatch: The check parameter is always None. The actual # patterns are configured in logwatch_rules. We do not have access to the actual # patterns here but just to the useless "None". In order not to complicate things # we simply display nothing here. if varname == "logwatch_rules": pass elif known_settings is not self._PARAMETERS_UNKNOWN: try: html.write_text(valuespec.value_to_html(known_settings)) except Exception as e: if active_config.debug: raise html.write_text( _("Invalid parameter %r: %s") % (known_settings, e)) else: # For match type "dict" it can be the case the rule define some of the keys # while other keys are taken from the factory defaults. We need to show the # complete outcoming value here. if rules and ruleset.match_type() == "dict": if (rulespec.factory_default is not Rulespec.NO_FACTORY_DEFAULT and rulespec.factory_default is not Rulespec.FACTORY_DEFAULT_UNUSED): fd = rulespec.factory_default.copy() fd.update(setting) setting = fd if valuespec and not rules: # show the default value if rulespec.factory_default is Rulespec.FACTORY_DEFAULT_UNUSED: # Some rulesets are ineffective if they are empty html.write_text(_("(unused)")) elif rulespec.factory_default is not Rulespec.NO_FACTORY_DEFAULT: # If there is a factory default then show that one setting = rulespec.factory_default html.write_text(valuespec.value_to_html(setting)) elif ruleset.match_type() in ("all", "list"): # Rulesets that build lists are empty if no rule matches html.write_text(_("(no entry)")) else: # Else we use the default value of the valuespec html.write_text( valuespec.value_to_html(valuespec.default_value())) # We have a setting elif valuespec: if ruleset.match_type() == "all": for s in setting: html.write_text(valuespec.value_to_html(s)) else: html.write_text(valuespec.value_to_html(setting)) # Binary rule, no valuespec, outcome is True or False else: icon_name = "rule_%s%s" % ("yes" if setting else "no", "_off" if not rules else "") html.icon(icon_name, title=_("yes") if setting else _("no")) html.close_td() html.close_tr() html.close_table()
def _show_patterns(self): import cmk.gui.logwatch as logwatch collection = SingleRulesetRecursively("logwatch_rules") collection.load() ruleset = collection.get("logwatch_rules") html.h3(_("Logfile patterns")) if ruleset.is_empty(): html.open_div(class_="info") html.write_text( "There are no logfile patterns defined. You may create " 'logfile patterns using the <a href="%s">Rule Editor</a>.' % folder_preserving_link([ ("mode", "edit_ruleset"), ("varname", "logwatch_rules"), ])) html.close_div() # Loop all rules for this ruleset already_matched = False abs_rulenr = 0 for folder, rulenr, rule in ruleset.get_rules(): # Check if this rule applies to the given host/service if self._hostname: service_desc = self._get_service_description( self._hostname, "logwatch", self._item) # If hostname (and maybe filename) try match it rule_matches = rule.matches_host_and_item( Folder.current(), self._hostname, self._item, service_desc) else: # If no host/file given match all rules rule_matches = True with foldable_container( treename="rule", id_=str(abs_rulenr), isopen=True, title=HTML("<b>Rule #%d</b>" % (abs_rulenr + 1)), indent=False, ), table_element("pattern_editor_rule_%d" % abs_rulenr, sortable=False, css="logwatch") as table: abs_rulenr += 1 # TODO: What's this? pattern_list = rule.value if isinstance(pattern_list, dict): pattern_list = pattern_list["reclassify_patterns"] # Each rule can hold no, one or several patterns. Loop them all here for state, pattern, comment in pattern_list: match_class = "" disp_match_txt = HTML("") match_img = "" if rule_matches: # Applies to the given host/service matched = re.search(pattern, self._match_txt) if matched: # Prepare highlighted search txt match_start = matched.start() match_end = matched.end() disp_match_txt = ( escape_to_html(self._match_txt[:match_start]) + HTMLWriter.render_span( self._match_txt[match_start:match_end], class_="match") + escape_to_html(self._match_txt[match_end:])) if not already_matched: # First match match_class = "match first" match_img = "match" match_title = _( "This logfile pattern matches first and will be used for " "defining the state of the given line.") already_matched = True else: # subsequent match match_class = "match" match_img = "imatch" match_title = _( "This logfile pattern matches but another matched first." ) else: match_img = "nmatch" match_title = _( "This logfile pattern does not match the given string." ) else: # rule does not match match_img = "nmatch" match_title = _("The rule conditions do not match.") table.row() table.cell(_("Match")) html.icon("rule%s" % match_img, match_title) cls = ([ "state%d" % logwatch.level_state(state), "fillbackground" ] if match_class == "match first" else []) table.cell(_("State"), HTMLWriter.render_span( logwatch.level_name(state)), css=cls) table.cell(_("Pattern"), HTMLWriter.render_tt(pattern)) table.cell(_("Comment"), comment) table.cell(_("Matched line"), disp_match_txt) table.row(fixed=True) table.cell(colspan=5) edit_url = folder_preserving_link([ ("mode", "edit_rule"), ("varname", "logwatch_rules"), ("rulenr", rulenr), ("item", mk_repr(self._item).decode()), ("rule_folder", folder.path()), ("rule_id", rule.id), ]) html.icon_button(edit_url, _("Edit this rule"), "edit")