PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/logadm.py |
""" Module for managing Solaris logadm based log rotations. """ import logging import shlex import salt.utils.args import salt.utils.decorators as decorators import salt.utils.files import salt.utils.stringutils log = logging.getLogger(__name__) default_conf = "/etc/logadm.conf" option_toggles = { "-c": "copy", "-l": "localtime", "-N": "skip_missing", } option_flags = { "-A": "age", "-C": "count", "-a": "post_command", "-b": "pre_command", "-e": "mail_addr", "-E": "expire_command", "-g": "group", "-m": "mode", "-M": "rename_command", "-o": "owner", "-p": "period", "-P": "timestmp", "-R": "old_created_command", "-s": "size", "-S": "max_size", "-t": "template", "-T": "old_pattern", "-w": "entryname", "-z": "compress_count", } def __virtual__(): """ Only work on Solaris based systems """ if "Solaris" in __grains__["os_family"]: return True return ( False, "The logadm execution module cannot be loaded: only available on Solaris.", ) def _arg2opt(arg): """ Turn a pass argument into the correct option """ res = [o for o, a in option_toggles.items() if a == arg] res += [o for o, a in option_flags.items() if a == arg] return res[0] if res else None def _parse_conf(conf_file=default_conf): """ Parse a logadm configuration file. """ ret = {} with salt.utils.files.fopen(conf_file, "r") as ifile: for line in ifile: line = salt.utils.stringutils.to_unicode(line).strip() if not line: continue if line.startswith("#"): continue splitline = line.split(" ", 1) ret[splitline[0]] = splitline[1] return ret def _parse_options(entry, options, include_unset=True): """ Parse a logadm options string """ log_cfg = {} options = shlex.split(options) if not options: return None ## identifier is entry or log? if entry.startswith("/"): log_cfg["log_file"] = entry else: log_cfg["entryname"] = entry ## parse options # NOTE: we loop over the options because values may exist multiple times index = 0 while index < len(options): # log file if index in [0, (len(options) - 1)] and options[index].startswith("/"): log_cfg["log_file"] = options[index] # check if toggle option elif options[index] in option_toggles: log_cfg[option_toggles[options[index]]] = True # check if flag option elif options[index] in option_flags and (index + 1) <= len(options): log_cfg[option_flags[options[index]]] = ( int(options[index + 1]) if options[index + 1].isdigit() else options[index + 1] ) index += 1 # unknown options else: if "additional_options" not in log_cfg: log_cfg["additional_options"] = [] if " " in options[index]: log_cfg["dditional_options"] = f"'{options[index]}'" else: log_cfg["additional_options"].append(options[index]) index += 1 ## turn additional_options into string if "additional_options" in log_cfg: log_cfg["additional_options"] = " ".join(log_cfg["additional_options"]) ## ensure we have a log_file # NOTE: logadm assumes logname is a file if no log_file is given if "log_file" not in log_cfg and "entryname" in log_cfg: log_cfg["log_file"] = log_cfg["entryname"] del log_cfg["entryname"] ## include unset if include_unset: # toggle optioons for name in option_toggles.values(): if name not in log_cfg: log_cfg[name] = False # flag options for name in option_flags.values(): if name not in log_cfg: log_cfg[name] = None return log_cfg def show_conf(conf_file=default_conf, name=None): """ Show configuration conf_file : string path to logadm.conf, defaults to /etc/logadm.conf name : string optional show only a single entry CLI Example: .. code-block:: bash salt '*' logadm.show_conf salt '*' logadm.show_conf name=/var/log/syslog """ cfg = _parse_conf(conf_file) # filter if name and name in cfg: return {name: cfg[name]} elif name: return {name: f"not found in {conf_file}"} else: return cfg def list_conf(conf_file=default_conf, log_file=None, include_unset=False): """ Show parsed configuration .. versionadded:: 2018.3.0 conf_file : string path to logadm.conf, defaults to /etc/logadm.conf log_file : string optional show only one log file include_unset : boolean include unset flags in output CLI Example: .. code-block:: bash salt '*' logadm.list_conf salt '*' logadm.list_conf log=/var/log/syslog salt '*' logadm.list_conf include_unset=False """ cfg = _parse_conf(conf_file) cfg_parsed = {} ## parse all options for entry in cfg: log_cfg = _parse_options(entry, cfg[entry], include_unset) cfg_parsed[ log_cfg["log_file"] if "log_file" in log_cfg else log_cfg["entryname"] ] = log_cfg ## filter if log_file and log_file in cfg_parsed: return {log_file: cfg_parsed[log_file]} elif log_file: return {log_file: f"not found in {conf_file}"} else: return cfg_parsed @decorators.memoize def show_args(): """ Show which arguments map to which flags and options. .. versionadded:: 2018.3.0 CLI Example: .. code-block:: bash salt '*' logadm.show_args """ mapping = {"flags": {}, "options": {}} for flag, arg in option_toggles.items(): mapping["flags"][flag] = arg for option, arg in option_flags.items(): mapping["options"][option] = arg return mapping def rotate(name, pattern=None, conf_file=default_conf, **kwargs): """ Set up pattern for logging. name : string alias for entryname pattern : string alias for log_file conf_file : string optional path to alternative configuration file kwargs : boolean|string|int optional additional flags and parameters .. note:: ``name`` and ``pattern`` were kept for backwards compatibility reasons. ``name`` is an alias for the ``entryname`` argument, ``pattern`` is an alias for ``log_file``. These aliases will only be used if the ``entryname`` and ``log_file`` arguments are not passed. For a full list of arguments see ```logadm.show_args```. CLI Example: .. code-block:: bash salt '*' logadm.rotate myapplog pattern='/var/log/myapp/*.log' count=7 salt '*' logadm.rotate myapplog log_file='/var/log/myapp/*.log' count=4 owner=myappd mode='0700' """ ## cleanup kwargs kwargs = salt.utils.args.clean_kwargs(**kwargs) ## inject name into kwargs if "entryname" not in kwargs and name and not name.startswith("/"): kwargs["entryname"] = name ## inject pattern into kwargs if "log_file" not in kwargs: if pattern and pattern.startswith("/"): kwargs["log_file"] = pattern # NOTE: for backwards compatibility check if name is a path elif name and name.startswith("/"): kwargs["log_file"] = name ## build command log.debug("logadm.rotate - kwargs: %s", kwargs) command = f"logadm -f {conf_file}" for arg, val in kwargs.items(): if arg in option_toggles.values() and val: command = "{} {}".format( command, _arg2opt(arg), ) elif arg in option_flags.values(): command = f"{command} {_arg2opt(arg)} {shlex.quote(str(val))}" elif arg != "log_file": log.warning("Unknown argument %s, don't know how to map this!", arg) if "log_file" in kwargs: # NOTE: except from ```man logadm``` # If no log file name is provided on a logadm command line, the entry # name is assumed to be the same as the log file name. For example, # the following two lines achieve the same thing, keeping two copies # of rotated log files: # # % logadm -C2 -w mylog /my/really/long/log/file/name # % logadm -C2 -w /my/really/long/log/file/name if "entryname" not in kwargs: command = "{} -w {}".format(command, shlex.quote(kwargs["log_file"])) else: command = "{} {}".format(command, shlex.quote(kwargs["log_file"])) log.debug("logadm.rotate - command: %s", command) result = __salt__["cmd.run_all"](command, python_shell=False) if result["retcode"] != 0: return dict(Error="Failed in adding log", Output=result["stderr"]) return dict(Result="Success") def remove(name, conf_file=default_conf): """ Remove log pattern from logadm CLI Example: .. code-block:: bash salt '*' logadm.remove myapplog """ command = f"logadm -f {conf_file} -r {name}" result = __salt__["cmd.run_all"](command, python_shell=False) if result["retcode"] != 0: return dict( Error="Failure in removing log. Possibly already removed?", Output=result["stderr"], ) return dict(Result="Success")