def _fetch_agent_output(self, job_interface): job_interface.send_progress_update( _("Fetching '%s'...") % self._request.agent_type) agent_output_result = get_agent_output( self._request.host.site_id(), self._request.host.name(), self._request.agent_type, ) if not agent_output_result.success: job_interface.send_progress_update( _("Failed: %s") % agent_output_result.service_details) preview_filepath = os.path.join( job_interface.get_work_dir(), AgentOutputPage.file_name(self._request)) store.save_text_to_file( preview_filepath, agent_output_result.raw_agent_data.decode("utf-8"), ) download_url = makeuri_contextless( request, [("host", self._request.host.name()), ("type", self._request.agent_type)], filename="download_agent_output.py", ) button = html.render_icon_button(download_url, _("Download"), "agent_output") job_interface.send_progress_update("Job finished.") job_interface.send_result_message( _("%s Click on the icon to download the agent output.") % button)
def _create_nagvis_backends(sites_config): cfg = [ "; MANAGED BY CHECK_MK WATO - Last Update: %s" % time.strftime("%Y-%m-%d %H:%M:%S"), ] for site_id, site in sites_config.items(): if site == omd_site(): continue # skip local site, backend already added by omd socket = _encode_socket_for_nagvis(site_id, site) cfg += [ "", "[backend_%s]" % site_id, 'backendtype="mklivestatus"', 'socket="%s"' % socket, ] if site.get("status_host"): cfg.append('statushost="%s"' % ":".join(site["status_host"])) if site["proxy"] is None and is_livestatus_encrypted(site): address_spec = site["socket"][1] tls_settings = address_spec["tls"][1] cfg.append("verify_tls_peer=%d" % tls_settings["verify"]) cfg.append("verify_tls_ca_path=%s" % ConfigDomainCACertificates.trusted_cas_file) store.save_text_to_file( "%s/etc/nagvis/conf.d/cmk_backends.ini.php" % cmk.utils.paths.omd_root, "\n".join(cfg))
def save(self, entries): # type: (Dict[str, str]) -> None """Save the dictionary entries (unicode username and hash) to the htpasswd file""" output = u"\n".join(u"%s:%s" % (six.ensure_text(e[0]), six.ensure_text(e[1])) for e in sorted(entries.items())) + u"\n" store.save_text_to_file("%s" % self._path, output)
def export_rule_pack(rule_pack: ECRulePack, pretty_print: bool = False, dir_: Optional[Path] = None) -> None: """ Export the representation of a rule pack (i.e. a dict) to a .mk file accessible by the WATO module Extension Packages. In case of a MkpRulePackProxy the representation of the underlying rule pack is used. The name of the .mk file is determined by the ID of the rule pack, i.e. the rule pack 'test' will be saved as 'test.mk' By default the rule pack is saved to the default directory for mkp rule packs. If dir_ is given the default is replaced by the directory dir_. """ if isinstance(rule_pack, MkpRulePackProxy): if rule_pack.rule_pack is None: raise MkpRulePackBindingError("Proxy is not bound") rule_pack = rule_pack.rule_pack repr_ = pprint.pformat(rule_pack) if pretty_print else repr(rule_pack) output = ("# Written by WATO\n" "# encoding: utf-8\n" "\n" "mkp_rule_packs['%s'] = \\\n" "%s\n") % (rule_pack["id"], repr_) if not dir_: dir_ = mkp_rule_pack_dir() dir_.mkdir(parents=True, exist_ok=True) store.save_text_to_file(dir_ / ("%s.mk" % rule_pack["id"]), str(output))
def _store_result( *, path: Path, serialized_result: SerializedResult, automation_cmd: str, cmdline_cmd: Iterable[str], ) -> None: if remote_automation_call_came_from_pre21(): try: store.save_object_to_file( path, result_type_registry[automation_cmd].deserialize( serialized_result).to_pre_21(), ) except SyntaxError as e: raise local_automation_failure( command=automation_cmd, cmdline=cmdline_cmd, out=serialized_result, exc=e, ) else: store.save_text_to_file( path, serialized_result, )
def _fetch_agent_output(self, job_interface): job_interface.send_progress_update( _("Fetching '%s'...") % self._request.agent_type) success, output, agent_data = watolib.check_mk_automation( self._request.host.site_id(), "get-agent-output", [self._request.host.name(), self._request.agent_type]) if not success: job_interface.send_progress_update(_("Failed: %s") % output) preview_filepath = os.path.join( job_interface.get_work_dir(), AgentOutputPage.file_name(self._request)) store.save_text_to_file(preview_filepath, agent_data) download_url = makeuri_contextless( request, [("host", self._request.host.name()), ("type", self._request.agent_type)], filename="download_agent_output.py", ) button = html.render_icon_button(download_url, _("Download"), "agent_output") job_interface.send_progress_update( _("Finished. Click on the icon to download the data.")) job_interface.send_result_message(_("%s Finished.") % button)
def _delete_distributed_wato_file(): p = cmk.utils.paths.check_mk_config_dir + "/distributed_wato.mk" # We do not delete the file but empty it. That way # we do not need write permissions to the conf.d # directory! if os.path.exists(p): store.save_text_to_file(p, "")
def save_updated_host_label_files( updated_host_labels: List[UpdatedHostLabelsEntry]) -> None: """Persists the data previously read by get_updated_host_label_files()""" for file_name, mtime, content in updated_host_labels: file_path = cmk.utils.paths.discovered_host_labels_dir / file_name store.save_text_to_file(file_path, content) os.utime(file_path, (mtime, mtime))
def _store_last_event_ids( self, ids: Iterable[int], ) -> None: store.save_text_to_file( self._path_last_event_ids, json.dumps(list(ids)), )
def add_or_get_files(self, tmp_dump_folder: Path, collectors: Collectors) -> DiagnosticsElementFilepaths: infos = self._collect_infos(collectors) if not infos: raise DiagnosticsElementError("No information") filepath = tmp_dump_folder.joinpath(self.ident).with_suffix(".json") store.save_text_to_file(filepath, json.dumps(infos)) yield filepath
def save_custom_attrs_to_mk_file(attrs): output = watolib.wato_fileheader() for what in ["user", "host"]: if what in attrs and len(attrs[what]) > 0: output += "if type(wato_%s_attrs) != list:\n wato_%s_attrs = []\n" % (what, what) output += "wato_%s_attrs += %s\n\n" % (what, pprint.pformat(attrs[what])) store.mkdir(watolib.multisite_dir()) store.save_text_to_file(watolib.multisite_dir() + "custom_attrs.mk", output)
def save_to(self, path, filename, pretty=False): filepath = "%s/%s" % (path, filename) output = self.get_raw_tree() store.save_object_to_file(filepath, output, pretty=pretty) # TODO: Can be set to encoding="utf-8" once we are on Python 3 only with gzip.open(filepath + ".gz", "wb") as f: f.write(ensure_binary(repr(output) + "\n")) # Inform Livestatus about the latest inventory update store.save_text_to_file("%s/.last" % path, u"")
def _write_config_file(self): config = self._get_effective_config() output = wato_fileheader() for key, val in sorted(config.get("rrdcached_tuning", {}).items()): output += "%s=%d\n" % (key, val) config_file_path = os.path.join(cmk.utils.paths.omd_root, "etc/rrdcached.d", "zzz_check_mk.conf") store.save_text_to_file(config_file_path, output)
def save_to(self, path, filename, pretty=False): filepath = "%s/%s" % (path, filename) output = self.get_raw_tree() store.save_object_to_file(filepath, output, pretty=pretty) buf = io.BytesIO() with gzip.GzipFile(fileobj=buf, mode="wb") as f: f.write((repr(output) + "\n").encode("utf-8")) store.save_file(filepath + ".gz", buf.getvalue()) # Inform Livestatus about the latest inventory update store.save_text_to_file("%s/.last" % path, u"")
def save_autochecks_file( hostname: HostName, services: Sequence[Service], ) -> None: path = _autochecks_path_for(hostname) path.parent.mkdir(parents=True, exist_ok=True) content = [] content.append("[") for service in sorted(services): content.append(" %s," % service.dump_autocheck()) content.append("]\n") store.save_text_to_file(path, "\n".join(content))
def save_config(self) -> None: store.save_text_to_file(self._bi_configuration_file, repr(self.generate_config())) enabled_aggregations = str( len([ bi_aggr for bi_aggr in self.get_all_aggregations() if not bi_aggr.computation_options.disabled ])) store.makedirs(self._num_enabled_aggregations_dir()) store.save_text_to_file(self._num_enabled_aggregations_path(), enabled_aggregations)
def _update_trusted_cas(self, current_config) -> ConfigurationWarnings: trusted_cas: List[str] = [] errors: ConfigurationWarnings = [] if current_config["use_system_wide_cas"]: trusted, errors = self._get_system_wide_trusted_ca_certificates() trusted_cas += trusted trusted_cas += current_config["trusted_cas"] store.save_text_to_file(self.trusted_cas_file, "\n".join(trusted_cas)) return errors
def save(self, settings, site_specific=False, custom_site_path=None): filename = self.config_file(site_specific) if custom_site_path: filename = os.path.join( custom_site_path, os.path.relpath(filename, cmk.utils.paths.omd_root)) output = wato_fileheader() for varname, value in settings.items(): output += "%s = %s\n" % (varname, pprint.pformat(value)) store.makedirs(os.path.dirname(filename)) store.save_text_to_file(filename, output)
def recreate_openapi_spec(mocker, _cache=[]): # pylint: disable=dangerous-default-value from cmk.gui.openapi import generate # pylint: disable=import-outside-toplevel spec_path = paths.omd_root + "/share/checkmk/web/htdocs/openapi" openapi_spec_dir = mocker.patch('cmk.gui.wsgi.applications.rest_api') openapi_spec_dir.return_value = spec_path if not _cache: with SPEC_LOCK: if not _cache: _cache.append(generate()) spec_data = six.ensure_text(_cache[0]) store.save_text_to_file(spec_path + "/checkmk.yaml", spec_data)
def _write_config_file(self): config = self.get_effective_config() output = wato_fileheader() if config: output += "ServerLimit %d\n" % config["apache_process_tuning"]["number_of_processes"] output += "MaxClients %d\n" % config["apache_process_tuning"]["number_of_processes"] config_file_path = os.path.join( cmk.utils.paths.omd_root, "etc/apache/conf.d", "zzz_check_mk.conf" ) store.save_text_to_file(config_file_path, output)
def _check_compilation_status(self) -> None: current_configstatus = self.compute_current_configstatus() if not self._compilation_required(current_configstatus): self._logger.debug("No compilation required") return with store.locked(self._path_compilation_lock): # Re-check compilation required after lock has been required # Another apache might have done the job current_configstatus = self.compute_current_configstatus() if not self._compilation_required(current_configstatus): self._logger.debug( "No compilation required. An other process already compiled it" ) return self.prepare_for_compilation(current_configstatus["online_sites"]) # Compile the raw tree for aggregation in self._bi_packs.get_all_aggregations(): start = time.time() self._compiled_aggregations[ aggregation.id] = aggregation.compile(self.bi_searcher) self._logger.debug("Compilation of %s took %f" % (aggregation.id, time.time() - start)) self._verify_aggregation_title_uniqueness( self._compiled_aggregations) for aggr_id, aggr in self._compiled_aggregations.items(): start = time.time() result = aggr.serialize() self._logger.debug( "Schema dump %s took config took %f (%d branches)" % (aggr_id, time.time() - start, len(aggr.branches))) self._save_data( self._path_compiled_aggregations.joinpath(aggr_id), result) self._generate_part_of_aggregation_lookup( self._compiled_aggregations) known_sites = { kv[0]: kv[1] for kv in current_configstatus.get("known_sites", set()) } self._cleanup_vanished_aggregations() self._bi_structure_fetcher.cleanup_orphaned_files(known_sites) store.save_text_to_file( str(self._path_compilation_timestamp), str(current_configstatus["configfile_timestamp"]))
def _try_history_update() -> None: logger.debug("Try license usage history update.") license_usage_dir.mkdir(parents=True, exist_ok=True) with store.locked(next_run_filepath), store.locked(history_filepath): now = datetime.now() next_run_ts = int(rot47(store.load_text_from_file(next_run_filepath, default="_"))) if not _may_update(now.timestamp(), next_run_ts): return history_dump = _create_or_update_history_dump() store.save_bytes_to_file(history_filepath, history_dump.serialize()) store.save_text_to_file(next_run_filepath, rot47(str(_create_next_run_ts(now)))) logger.debug("Successfully updated history.")
def _upload_csv_file(self) -> None: store.makedirs(self._upload_tmp_path) self._cleanup_old_files() upload_info = self._vs_upload().from_html_vars("_upload") self._vs_upload().validate_value(upload_info, "_upload") file_id = uuid.uuid4().hex store.save_text_to_file(self._file_path(file_id=file_id), upload_info["file"]) # make selections available to next page request.set_var("file_id", file_id) if upload_info["do_service_detection"]: request.set_var("do_service_detection", "1")
def _update_trusted_cas(self, current_config) -> ConfigurationWarnings: trusted_cas: List[str] = [] errors: ConfigurationWarnings = [] if current_config["use_system_wide_cas"]: trusted, errors = self._get_system_wide_trusted_ca_certificates() trusted_cas += trusted trusted_cas += current_config["trusted_cas"] store.save_text_to_file( self.trusted_cas_file, # we sort to have a deterministic output, s.t. for example liveproxyd can reliably check # if the file changed "\n".join(sorted(trusted_cas)), ) return errors
def save(self, crash: 'ABCCrashReport') -> None: """Save the crash report instance to it's crash report directory""" self._prepare_crash_dump_directory(crash) for key, value in crash.serialize().items(): fname = "crash.info" if key == "crash_info" else key if value is None: continue if fname == "crash.info": store.save_text_to_file(crash.crash_dir() / fname, str(json.dumps(value, cls=RobustJSONEncoder)) + "\n") else: store.save_bytes_to_file(crash.crash_dir() / fname, value) self._cleanup_old_crashes(crash.crash_dir().parent)
def _upload_csv_file(self) -> None: store.makedirs(self._upload_tmp_path) self._cleanup_old_files() upload_info = self._vs_upload().from_html_vars("_upload") self._vs_upload().validate_value(upload_info, "_upload") file_id = "%s-%d" % (config.user.id, int(time.time())) store.save_text_to_file(self._file_path(), upload_info["file"]) # make selections available to next page html.request.set_var("file_id", file_id) if upload_info["do_service_detection"]: html.request.set_var("do_service_detection", "1")
def save_tree_to( tree: "StructuredDataNode", path: str, filename: str, pretty: bool = False, ) -> None: filepath = "%s/%s" % (path, filename) output = tree.get_raw_tree() store.save_object_to_file(filepath, output, pretty=pretty) buf = io.BytesIO() with gzip.GzipFile(fileobj=buf, mode="wb") as f: f.write((repr(output) + "\n").encode("utf-8")) store.save_bytes_to_file(filepath + ".gz", buf.getvalue()) # Inform Livestatus about the latest inventory update store.save_text_to_file("%s/.last" % path, u"")
def disksync( self, *, removed: Container[_TKey] = (), updated: Iterable[Tuple[_TKey, _TValue]] = (), ) -> None: """Re-load and write the changes of the stored values This method will reload the values from disk, apply the changes (remove keys and update values) as specified by the arguments, and then write the result to disk. When this method returns, the data provided via the Mapping-interface and the data stored on disk must be in sync. """ self._log_debug("synchronizing") self._path.parent.mkdir(parents=True, exist_ok=True) try: store.aquire_lock(self._path) if self._path.stat().st_mtime == self._last_sync: self._log_debug("already loaded") else: self._log_debug("loading from disk") self._data = self._deserializer( store.load_text_from_file(self._path, default="{}", lock=False)) if removed or updated: data = { k: v for k, v in self._data.items() if k not in removed } data.update(updated) self._log_debug("writing to disk") store.save_text_to_file(self._path, self._serializer(data)) self._data = data self._last_sync = self._path.stat().st_mtime except Exception as exc: raise MKGeneralException from exc finally: store.release_lock(self._path)
def save_rule_packs(rule_packs, pretty_print=False, dir_=None): # type: (ECRulePacks, bool, Optional[Path]) -> None """Saves the given rule packs to rules.mk. By default they are saved to the default directory for rule packs. If dir_ is given it is used instead of the default.""" output = "# Written by WATO\n# encoding: utf-8\n\n" if pretty_print: rule_packs_text = pprint.pformat(rule_packs) else: rule_packs_text = repr(rule_packs) output += "rule_packs += \\\n%s\n" % rule_packs_text if not dir_: dir_ = rule_pack_dir() dir_.mkdir(parents=True, exist_ok=True) store.save_text_to_file(dir_ / "rules.mk", ensure_str(output))
def save_group_information(all_groups, custom_default_config_dir=None): # Split groups data into Checkmk/Multisite parts check_mk_groups: Dict[str, Dict[Any, Any]] = {} multisite_groups: Dict[str, Dict[Any, Any]] = {} if custom_default_config_dir: check_mk_config_dir = "%s/conf.d/wato" % custom_default_config_dir multisite_config_dir = "%s/multisite.d/wato" % custom_default_config_dir else: check_mk_config_dir = "%s/conf.d/wato" % cmk.utils.paths.default_config_dir multisite_config_dir = "%s/multisite.d/wato" % cmk.utils.paths.default_config_dir for what, groups in all_groups.items(): check_mk_groups[what] = {} for gid, group in groups.items(): check_mk_groups[what][gid] = group['alias'] for attr, value in group.items(): if attr != 'alias': multisite_groups.setdefault(what, {}) multisite_groups[what].setdefault(gid, {}) multisite_groups[what][gid][attr] = value # Save Checkmk world related parts store.makedirs(check_mk_config_dir) output = wato_fileheader() for what in ["host", "service", "contact"]: if check_mk_groups.get(what): output += "if type(define_%sgroups) != dict:\n define_%sgroups = {}\n" % ( what, what) output += "define_%sgroups.update(%s)\n\n" % ( what, format_config_value(check_mk_groups[what])) store.save_text_to_file("%s/groups.mk" % check_mk_config_dir, output) # Users with passwords for Multisite store.makedirs(multisite_config_dir) output = wato_fileheader() for what in ["host", "service", "contact"]: if multisite_groups.get(what): output += "multisite_%sgroups = \\\n%s\n\n" % ( what, format_config_value(multisite_groups[what])) store.save_text_to_file("%s/groups.mk" % multisite_config_dir, output) _clear_group_information_request_cache()