import os.path
import time
import re
-import glob
import logging
logger = logging.getLogger("filestore")
+
class InvalidAgeFormatError(Exception):
pass
+
def register_args(parser):
parsers = parser.add_subparsers()
-
prune_parser = parsers.add_parser("prune")
prune_parser.add_argument("-d", "--directory", help="filestore directory")
prune_parser.add_argument("--age", help="prune files older than age")
prune_parser.add_argument(
"-n", "--dry-run", action="store_true", default=False,
- help="only print what would happen");
+ help="only print what would happen")
prune_parser.add_argument(
"-v", "--verbose", action="store_true",
default=False, help="increase verbosity")
help="be quiet, log warnings and errors only")
prune_parser.set_defaults(func=prune)
+
def is_fileinfo(path):
return path.endswith(".json")
+
def parse_age(age):
- m = re.match("(\d+)\s*(\w+)", age)
- if not m:
+ matched_age = re.match(r"(\d+)\s*(\w+)", age)
+ if not matched_age:
raise InvalidAgeFormatError(age)
- val = int(m.group(1))
- unit = m.group(2)
-
+ val = int(matched_age.group(1))
+ unit = matched_age.group(2)
if unit == "s":
return val
- elif unit == "m":
+ if unit == "m":
return val * 60
- elif unit == "h":
+ if unit == "h":
return val * 60 * 60
- elif unit == "d":
+ if unit == "d":
return val * 60 * 60 * 24
- else:
- raise InvalidAgeFormatError("bad unit: %s" % (unit))
+ raise InvalidAgeFormatError("bad unit: %s" % (unit))
+
def get_filesize(path):
return os.stat(path).st_size
+
def remove_file(path, dry_run):
size = 0
size += get_filesize(path)
os.unlink(path)
return size
+
def prune(args):
if args.verbose:
"error: the filestore directory must be provided with --directory",
file=sys.stderr)
return 1
-
+
if not args.age:
print("error: no age provided, nothing to do", file=sys.stderr)
return 1
count = 0
for dirpath, dirnames, filenames in os.walk(args.directory, topdown=True):
-
# Do not go into the tmp directory.
if "tmp" in dirnames:
dirnames.remove("tmp")
mtime = os.path.getmtime(path)
this_age = now - mtime
if this_age > age:
- logger.debug("Deleting %s; age=%ds" % (path, this_age))
+ logger.debug("Deleting %s; age=%ds", path, this_age)
size += remove_file(path, args.dry_run)
count += 1
- logger.info("Removed %d files; %d bytes." % (count, size))
+ logger.info("Removed %d files; %d bytes.", count, size)
+ return 0
"""An alternative stream log handler that logs with Suricata inspired
log colours."""
- def formatTime(self, record):
- lt = time.localtime(record.created)
- t = "%d/%d/%d -- %02d:%02d:%02d" % (lt.tm_mday,
- lt.tm_mon,
- lt.tm_year,
- lt.tm_hour,
- lt.tm_min,
- lt.tm_sec)
- return "%s" % (t)
+ @staticmethod
+ def format_time(record):
+ local_time = time.localtime(record.created)
+ formatted_time = "%d/%d/%d -- %02d:%02d:%02d" % (local_time.tm_mday,
+ local_time.tm_mon,
+ local_time.tm_year,
+ local_time.tm_hour,
+ local_time.tm_min,
+ local_time.tm_sec)
+ return "%s" % (formatted_time)
def emit(self, record):
self.stream.write("%s%s%s - <%s%s%s> -- %s%s%s\n" % (
GREEN,
- self.formatTime(record),
+ self.format_time(record),
RESET,
level_prefix,
record.levelname.title(),
self.mask_secrets(record.getMessage()),
RESET))
- def mask_secrets(self, msg):
+ @staticmethod
+ def mask_secrets(msg):
for secret in secrets:
msg = msg.replace(secret, "<%s>" % secrets[secret])
return msg
import argparse
import logging
-from suricata.ctl import filestore
-from suricata.ctl import loghandler
+from suricata.ctl import filestore, loghandler
def init_logger():
""" Initialize logging, use colour if on a tty. """
format="%(asctime)s - <%(levelname)s> - %(message)s")
def main():
-
init_logger()
-
parser = argparse.ArgumentParser(description="Suricata Control Tool")
-
subparsers = parser.add_subparsers(
title="subcommands",
description="Commands")
-
filestore.register_args(subparsers.add_parser("filestore"))
-
args = parser.parse_args()
try:
func = args.func