# Path: src/imgbased/openscap.py
# class OSCAPScanner(object):
#     def __init__(self):
#         if not os.path.exists(SCAP_REPORTSDIR):
#             os.makedirs(SCAP_REPORTSDIR, mode=0o550)
#         self._config = OSCAPConfig()
# 
#     def process(self, path):
#         if self._config.registered:
#             self.scan(remediate=True, path=path)
#         else:
#             self.configure()
# 
#     def register(self, datastream, profile):
#         log.info("Registering profile %s from %s", profile, datastream)
#         if profile not in self.profiles(datastream):
#             log.error("Profile %s not found", profile)
#             return
#         self._config.datastream = os.path.realpath(datastream)
#         self._config.profile = profile
# 
#     def unregister(self, profile):
#         if profile == self._config.profile:
#             log.info("Unregistering profile %s", profile)
#             self._config.profile = ""
#         else:
#             log.warn("Profile [%s] is not registered, skipping", profile)
# 
#     def scan(self, remediate=False, path="/"):
#         log.debug("Running OSCAP scan on %s, (remediate=%s)", path, remediate)
#         if not self._config.registered:
#             log.warn("Security profile not registered, skipping")
#             return
#         report = SCAP_REPORT_FMT % time.strftime("%Y%m%d%H%M%S")
#         args = ["chroot", path, "oscap", "xccdf", "eval",
#                 "--profile", self.profile, "--report", report]
#         if remediate:
#             args.append("--remediate")
#         args.append(self._config.datastream)
#         with bindmounted("/proc", path + "/proc"):
#             with bindmounted("/var", path + "/var", rbind=True):
#                 nsenter(args)
#         log.info("Report available at %s", report)
# 
#     def profiles(self, datastream=None):
#         if not datastream:
#             datastream = self._config.datastream
#         if not datastream or not File(datastream).exists():
#             raise ScapDatastreamError("Datastream not found: %s" % datastream)
#         cmd = ["oscap", "info", "--profiles", datastream]
#         stdout = nsenter(cmd).decode(errors="replace")
#         profiles = dict([x.split(":") for x in stdout.splitlines()])
#         log.debug("Collected OSCAP profiles: %s", profiles)
#         return profiles
# 
#     @property
#     def profile(self):
#         if not self._config.registered:
#             raise ScapProfileError("SCAP profile not registered")
#         return self._config.profile
# 
#     def configure(self):
#         if self._config.configured:
#             log.debug("SCAP was already auto-configured, skipping")
#             return
#         self._config.configured = "1"
#         j = journal.Reader()
#         j.this_boot()
#         j.add_match(SYSLOG_IDENTIFIER="oscap")
#         msgs = [x for x in j if x["MESSAGE"].startswith("Evaluation started")]
#         if not msgs:
#             log.info("No SCAP evaluation found, skipping")
#             return
#         ds, profile = [x[:-1] for x in msgs[0]["MESSAGE"].split()[3::2]]
#         self.register(ds, profile)


import logging
from ..openscap import OSCAPScanner


log = logging.getLogger(__package__)


def init(app):
    app.hooks.connect("pre-arg-parse", add_argparse)
    app.hooks.connect("post-arg-parse", post_argparse)


def add_argparse(app, parser, subparsers):
    s = subparsers.add_parser("openscap", help="Security management")
    s.add_argument("--all", action="store_true",
                   help="List all available profiles")
    s.add_argument("--list", action="store_true",
                   help="List registered profile")
    s.add_argument("--configure", action="store_true",
                   help="Auto configure SCAP profile and datastream")
    s.add_argument("--register", nargs=2, metavar=("DATASTREAM", "PROFILE"),
                   help="Register data for scanning")
    s.add_argument("--unregister", metavar="PROFILE",
                   help="Register data for scanning")
    s.add_argument("--scan", metavar="PATH",
                   help="Use registered profile to perform a scan")
    s.add_argument("--remediate", metavar="PATH",
                   help="Use registered profile to remediate system")


def post_argparse(app, args):
    if args.command == "openscap":

# Path: src/imgbased/openscap.py
# class OSCAPScanner(object):
#     def __init__(self):
#         if not os.path.exists(SCAP_REPORTSDIR):
#             os.makedirs(SCAP_REPORTSDIR, mode=0o550)
#         self._config = OSCAPConfig()
# 
#     def process(self, path):
#         if self._config.registered:
#             self.scan(remediate=True, path=path)
#         else:
#             self.configure()
# 
#     def register(self, datastream, profile):
#         log.info("Registering profile %s from %s", profile, datastream)
#         if profile not in self.profiles(datastream):
#             log.error("Profile %s not found", profile)
#             return
#         self._config.datastream = os.path.realpath(datastream)
#         self._config.profile = profile
# 
#     def unregister(self, profile):
#         if profile == self._config.profile:
#             log.info("Unregistering profile %s", profile)
#             self._config.profile = ""
#         else:
#             log.warn("Profile [%s] is not registered, skipping", profile)
# 
#     def scan(self, remediate=False, path="/"):
#         log.debug("Running OSCAP scan on %s, (remediate=%s)", path, remediate)
#         if not self._config.registered:
#             log.warn("Security profile not registered, skipping")
#             return
#         report = SCAP_REPORT_FMT % time.strftime("%Y%m%d%H%M%S")
#         args = ["chroot", path, "oscap", "xccdf", "eval",
#                 "--profile", self.profile, "--report", report]
#         if remediate:
#             args.append("--remediate")
#         args.append(self._config.datastream)
#         with bindmounted("/proc", path + "/proc"):
#             with bindmounted("/var", path + "/var", rbind=True):
#                 nsenter(args)
#         log.info("Report available at %s", report)
# 
#     def profiles(self, datastream=None):
#         if not datastream:
#             datastream = self._config.datastream
#         if not datastream or not File(datastream).exists():
#             raise ScapDatastreamError("Datastream not found: %s" % datastream)
#         cmd = ["oscap", "info", "--profiles", datastream]
#         stdout = nsenter(cmd).decode(errors="replace")
#         profiles = dict([x.split(":") for x in stdout.splitlines()])
#         log.debug("Collected OSCAP profiles: %s", profiles)
#         return profiles
# 
#     @property
#     def profile(self):
#         if not self._config.registered:
#             raise ScapProfileError("SCAP profile not registered")
#         return self._config.profile
# 
#     def configure(self):
#         if self._config.configured:
#             log.debug("SCAP was already auto-configured, skipping")
#             return
#         self._config.configured = "1"
#         j = journal.Reader()
#         j.this_boot()
#         j.add_match(SYSLOG_IDENTIFIER="oscap")
#         msgs = [x for x in j if x["MESSAGE"].startswith("Evaluation started")]
#         if not msgs:
#             log.info("No SCAP evaluation found, skipping")
#             return
#         ds, profile = [x[:-1] for x in msgs[0]["MESSAGE"].split()[3::2]]
#         self.register(ds, profile)


# Path: src/imgbased/plugins/openscap.py
import logging
from ..openscap import OSCAPScanner



log = logging.getLogger(__package__)


def init(app):
    app.hooks.connect("pre-arg-parse", add_argparse)
    app.hooks.connect("post-arg-parse", post_argparse)


def add_argparse(app, parser, subparsers):
    s = subparsers.add_parser("openscap", help="Security management")
    s.add_argument("--all", action="store_true",
                   help="List all available profiles")
    s.add_argument("--list", action="store_true",
                   help="List registered profile")
    s.add_argument("--configure", action="store_true",
                   help="Auto configure SCAP profile and datastream")
    s.add_argument("--register", nargs=2, metavar=("DATASTREAM", "PROFILE"),
                   help="Register data for scanning")
    s.add_argument("--unregister", metavar="PROFILE",
                   help="Register data for scanning")
    s.add_argument("--scan", metavar="PATH",
                   help="Use registered profile to perform a scan")
    s.add_argument("--remediate", metavar="PATH",
                   help="Use registered profile to remediate system")


def post_argparse(app, args):
    if args.command == "openscap":

        os = OSCAPScanner()