mirror of
https://github.com/aquasecurity/kube-hunter.git
synced 2026-08-23 22:26:23 +00:00
Separate report "sending" into modules (#156)
* moved report output into dispatchers, stdout by default with config option of http(s) * notes in arg config on how to configure http dispatcher * removed some debug log visibility indicators * missing import * env vars more descriptive: KUBEHUNTER_HTTP_DISPATCH_METHOD and KUBEHUNTER_HTTP_DISPATCH_URL * optimisation: delayed instantiation of the dispatcher until after selection to avoid instantiating unnecessarily * refactor: config selection as per reporter selection * bugfix: fall-back to default required if unknown reporter or dispatcher specified * swapping urllib3 for requests * corrected visibility levels for logging * moving dispatchers into a file in reporters rather than it's own place to fit with theme and support dynamic module loading
This commit is contained in:
+21
-6
@@ -15,6 +15,7 @@ parser.add_argument('--remote', nargs='+', metavar="HOST", default=list(), help=
|
||||
parser.add_argument('--active', action="store_true", help="enables active hunting")
|
||||
parser.add_argument('--log', type=str, metavar="LOGLEVEL", default='INFO', help="set log level, options are: debug, info, warn, none")
|
||||
parser.add_argument('--report', type=str, default='plain', help="set report type, options are: plain, yaml, json")
|
||||
parser.add_argument('--dispatch', type=str, default='stdout', help="where to send the report to, options are: stdout, http (use KUBEHUNTER_HTTP_DISPATCH_URL and KUBEHUNTER_HTTP_DISPATCH_METHOD to configure)")
|
||||
parser.add_argument('--statistics', action="store_true", help="set hunting statistics")
|
||||
|
||||
import plugins
|
||||
@@ -31,13 +32,27 @@ if config.log.lower() != "none":
|
||||
from src.modules.report.plain import PlainReporter
|
||||
from src.modules.report.yaml import YAMLReporter
|
||||
from src.modules.report.json_reporter import JSONReporter
|
||||
|
||||
if config.report.lower() == "yaml":
|
||||
config.reporter = YAMLReporter()
|
||||
elif config.report.lower() == "json":
|
||||
config.reporter = JSONReporter()
|
||||
reporters = {
|
||||
'yaml': YAMLReporter,
|
||||
'json': JSONReporter,
|
||||
'plain': PlainReporter
|
||||
}
|
||||
if config.report.lower() in reporters.keys():
|
||||
config.reporter = reporters[config.report.lower()]()
|
||||
else:
|
||||
config.reporter = PlainReporter()
|
||||
logging.warning('Unknown reporter selected, using plain')
|
||||
config.reporter = reporters['plain']()
|
||||
|
||||
from src.modules.report.dispatchers import STDOUTDispatcher, HTTPDispatcher
|
||||
dispatchers = {
|
||||
'stdout': STDOUTDispatcher,
|
||||
'http': HTTPDispatcher
|
||||
}
|
||||
if config.dispatch.lower() in dispatchers.keys():
|
||||
config.dispatcher = dispatchers[config.dispatch.lower()]()
|
||||
else:
|
||||
logging.warning('Unknown dispatcher selected, using stdout')
|
||||
config.dispatcher = dispatchers['stdout']()
|
||||
|
||||
from src.core.events import handler
|
||||
from src.core.events.types import HuntFinished, HuntStarted
|
||||
|
||||
@@ -145,3 +145,7 @@ class HuntFinished(Event):
|
||||
|
||||
class HuntStarted(Event):
|
||||
pass
|
||||
|
||||
|
||||
class ReportDispatched(Event):
|
||||
pass
|
||||
|
||||
@@ -2,7 +2,7 @@ import logging
|
||||
|
||||
from __main__ import config
|
||||
from src.core.events import handler
|
||||
from src.core.events.types import Event, Service, Vulnerability, HuntFinished, HuntStarted
|
||||
from src.core.events.types import Event, Service, Vulnerability, HuntFinished, HuntStarted, ReportDispatched
|
||||
import threading
|
||||
|
||||
|
||||
@@ -82,10 +82,8 @@ class SendFullReport(object):
|
||||
|
||||
def execute(self):
|
||||
report = config.reporter.get_report()
|
||||
if config.report == "plain":
|
||||
logging.info("\n{div}\n{report}".format(div="-" * 10, report=report))
|
||||
else:
|
||||
print(report)
|
||||
config.dispatcher.dispatch(report)
|
||||
handler.publish_event(ReportDispatched())
|
||||
handler.publish_event(TablesPrinted())
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import logging
|
||||
import os
|
||||
import requests
|
||||
from __main__ import config
|
||||
|
||||
|
||||
class HTTPDispatcher(object):
|
||||
def dispatch(self, report):
|
||||
logging.info('Dispatching report via http')
|
||||
dispatchMethod = os.environ.get(
|
||||
'KUBEHUNTER_HTTP_DISPATCH_METHOD',
|
||||
'POST'
|
||||
).upper()
|
||||
dispatchURL = os.environ.get(
|
||||
'KUBEHUNTER_HTTP_DISPATCH_URL',
|
||||
'https://localhost/'
|
||||
)
|
||||
logging.info(
|
||||
'Dispatching report via {method} to {url}'.format(
|
||||
method=dispatchMethod,
|
||||
url=dispatchURL
|
||||
)
|
||||
)
|
||||
try:
|
||||
r = requests.request(
|
||||
dispatchMethod,
|
||||
dispatchURL,
|
||||
json=report,
|
||||
headers={'Content-Type': 'application/json'}
|
||||
)
|
||||
r.raise_for_status()
|
||||
logging.info(
|
||||
"\tResponse Code: {status}\n\tResponse Data:\n{data}".format(
|
||||
status=r.status_code,
|
||||
data=r.text
|
||||
)
|
||||
)
|
||||
except requests.HTTPError as e:
|
||||
logging.error(
|
||||
"Dispatcher failed to deliver\n\tResponse Code: {status}\n\tResponse Data:\n{data}".format(
|
||||
status=r.status_code,
|
||||
data=r.text
|
||||
)
|
||||
)
|
||||
|
||||
class STDOUTDispatcher(object):
|
||||
def dispatch(self, report):
|
||||
logging.info('Dispatching report via stdout')
|
||||
if config.report == "plain":
|
||||
logging.info("\n{div}\n{report}".format(div="-" * 10, report=report))
|
||||
else:
|
||||
print(report)
|
||||
Reference in New Issue
Block a user