Skip to content

Commit

Permalink
Feature/#6 add clair scanner to ci (#7)
Browse files Browse the repository at this point in the history
Fixes #6 adds vuln scanner and current approved vulns to CI
  • Loading branch information
Ryan Faircloth authored and GitHub committed Jul 1, 2019
1 parent a6e7be6 commit 0c9b9f9
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 2 deletions.
32 changes: 31 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
version: 2.1

orbs:
clair_scanner: ovotech/clair-scanner@1

jobs:
build:
environment:
Expand Down Expand Up @@ -110,6 +114,27 @@ jobs:
when: always
- store_test_results:
path: test-results
test-scan_images:
environment:
IMAGE_NAME: rfaircloth/scs
executor: clair_scanner/default
steps:
- clair_scanner/scan:
image: $IMAGE_NAME:$CIRCLE_SHA1
whitelist: clair-whitelist.yml
- run:
command: |
mkdir -p /root/project/test-results
pip install -r requirements.txt
python clair_to_junit_parser.py "/clair-reports/$IMAGE_NAME:$CIRCLE_SHA1.json" --output test-results/results.xml
when: on_fail
# - store_test_results:
# path: test-results/results.xml
- store_artifacts:
path: test-results
- store_artifacts:
path: /clair-reports

publish:
environment:
IMAGE_NAME: rfaircloth/scs
Expand Down Expand Up @@ -138,7 +163,12 @@ workflows:
- dgoss:
requires:
- build
- test-unit
- test-unit:
requires:
- build
- test-scan_images:
requires:
- build
- publish:
requires:
- dgoss
Expand Down
8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions .idea/splunk-connect-for-syslog.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions clair-whitelist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
generalwhitelist:
RHSA-2019:1619: False Positive
RHSA-2018:0654: False Positive
RHSA-2018:1967: False Positive
RHSA-2017:0372: False Positive
RHSA-2018:0502: False Positive
RHSA-2018:2772: False Positive
RHSA-2018:1374: False Positive
RHSA-2018:0180: False Positive

images:
scs:
75 changes: 75 additions & 0 deletions clair_to_junit_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import json
from junit_xml import TestSuite, TestCase
import os
import argparse
import logging

logger = logging.getLogger('clair_scanner_converter')
logger.setLevel(logging.WARN)
console_logger = logging.StreamHandler()
console_logger.setLevel(logging.WARN)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_logger.setFormatter(formatter)
logger.addHandler(console_logger)

def parse_args():
parser = argparse.ArgumentParser(description="Process Json File")
parser.add_argument("clairfile", type=str, default=None, help="Location of clair scanner ouptut file to convert to cucumber.json")
parser.add_argument("--output", type=str, default=None, help="name of output file to store in new format. Defaults to clair inputfile")
args = parser.parse_args()
if not args.output:
logger.warning("No output file specified, replacing input file.")
args.output = args.clairfile
return args

def main():
cwd = os.getcwd()
args = parse_args()
try:
if os.path.exists(args.clairfile):
with open(args.clairfile) as clairfile:
clair_parsed_file = json.load(clairfile)
if os.path.exists(os.path.join("clair-scanner-logs", "/clair_setup_errors.log")):
with open(os.path.join("clair-scanner-logs", "/clair_setup_errors.log"), 'r') as clairfile_errors:
clair_parsed_error_file = clairfile_errors.readlines()
else:
clair_parsed_error_file = None
except:
logger.exception("Failed to parse clair / clair_error file. Exiting.")

current_sorted_level = None
current_suite = None
test_suites = []
if clair_parsed_error_file:
current_suite = TestSuite("SetupError")
new_step = TestCase(name="SetupError", classname="SetupError", status="unapproved", stderr=clair_parsed_error_file)
new_step.log = clair_parsed_error_file
new_step.category = "SetupError"
new_step.failure_type = "unapproved"
new_step.failure_message = "Please have the following security issue reviewed by Splunk: {}".format(vuln["link"])
new_step.failure_output = clair_parsed_error_file
current_suite.test_cases.append(new_step)
test_suites.append(current_suite)
for vuln in clair_parsed_file["vulnerabilities"]:
if current_sorted_level != vuln["severity"]:
if current_suite:
test_suites.append(current_suite)
current_suite = TestSuite(name=vuln["severity"])
current_sorted_level = vuln["severity"]
new_step = TestCase(name=vuln["vulnerability"], classname=vuln["severity"], status="unapproved", url=vuln["link"], stderr=vuln["description"])
new_step.log = vuln
new_step.category = vuln["severity"]
new_step.failure_type = "unapproved"
new_step.failure_message = "Please have the following security issue reviewed by Splunk: {}".format(vuln["link"])
new_step.failure_output = vuln["description"]
current_suite.test_cases.append(new_step)
# try to write new file
try:
with open(args.output, 'w') as outfile:
outfile.write(TestSuite.to_xml_string(test_suites))
except:
logger.exception("Filed saving file.")


if __name__ == "__main__":
main()
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
-r ./tests/requirements.txt

junit_xml
argparse

0 comments on commit 0c9b9f9

Please sign in to comment.