From 5327a05d467ff7f48089021bf7992df388da376b Mon Sep 17 00:00:00 2001 From: Stefan Fleckenstein Date: Fri, 5 Nov 2021 11:18:52 +0100 Subject: [PATCH] Support service attribute of DefectDojo (#15) * introduce service attribute * update version numbers for release * service in GH actions example * move service to dockle scan --- .github/workflows/dd-import_example.yml | 1 + .gitlab-ci.yml | 3 ++- README.md | 35 ++++++++++++++----------- dd_import/dd_api.py | 2 ++ dd_import/environment.py | 2 ++ setup.cfg | 2 +- unittests/test_api.py | 6 +++-- unittests/test_environment.py | 2 ++ 8 files changed, 34 insertions(+), 19 deletions(-) diff --git a/.github/workflows/dd-import_example.yml b/.github/workflows/dd-import_example.yml index 0b84cd5..009f415 100644 --- a/.github/workflows/dd-import_example.yml +++ b/.github/workflows/dd-import_example.yml @@ -32,6 +32,7 @@ jobs: DD_TEST_NAME: Semgrep DD_TEST_TYPE_NAME: Semgrep JSON Report DD_FILE_NAME: semgrep.json + DD_SERVICE: dd-import run: | dd-reimport-findings - name: Count lines of code diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7edfeff..1d37883 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,6 @@ variables: - DOCKER_ARTIFACT_URL: "maibornwolff/dd-import:1.0.2" + DOCKER_ARTIFACT_URL: "maibornwolff/dd-import:1.0.3" DD_PRODUCT_TYPE_NAME: "Showcase" DD_PRODUCT_NAME: "DefectDojo Importer" DD_ENGAGEMENT_NAME: "GitLab" @@ -118,6 +118,7 @@ upload-dockle: DD_TEST_NAME: "Dockle" DD_TEST_TYPE_NAME: "Dockle Scan" DD_FILE_NAME: "dockle.json" + DD_SERVICE: "dd-import" DD_BUILD_ID: "$CI_PIPELINE_ID" DD_COMMIT_HASH: "$CI_COMMIT_SHA" DD_BRANCH_TAG: "$CI_COMMIT_REF_NAME" diff --git a/README.md b/README.md index 711a73c..66e93ab 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ All parameters need to be provided as environment variables | DD_CLOSE_OLD_FINDINGS | Optional | - | Default: `true` | | DD_VERSION | Optional | - | | | DD_ENDPOINT_ID | Optional | - | | +| DD_SERVICE | Optional | - | | | DD_BUILD_ID | Optional | - | | | DD_COMMIT_HASH | Optional | - | | | DD_BRANCH_TAG | Optional | - | | @@ -85,17 +86,22 @@ variables: ... -safety: +trivy: stage: test - image: python:3.9-alpine tags: - build + variables: + GIT_STRATEGY: none + before_script: + - export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') + - echo $TRIVY_VERSION + - wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf - + allow_failure: true script: - - pip install safety - - safety check -r requirements.txt --json --output safety.json + - ./trivy --exit-code 0 --no-progress -f json -o trivy.json maibornwolff/dd-import:latest artifacts: paths: - - safety.json + - trivy.json when: always expire_in: 1 day @@ -114,18 +120,17 @@ cloc: when: always expire_in: 1 day -upload-safety: +upload_trivy: + stage: upload image: maibornwolff/dd-import:latest needs: - - job: safety + - job: trivy artifacts: true - stage: upload - tags: - - build variables: - DD_TEST_NAME: "Safety" - DD_TEST_TYPE_NAME: "Safety Scan" - DD_FILE_NAME: "safety.json" + GIT_STRATEGY: none + DD_TEST_NAME: "Trivy" + DD_TEST_TYPE_NAME: "Trivy Scan" + DD_FILE_NAME: "trivy.json" script: - /usr/local/dd-import/bin/dd-reimport-findings.sh @@ -144,9 +149,9 @@ upload-cloc: ``` - ***variables*** - Definition of some environment variables that will be used for several uploads. `DD_URL` and `DD_API_KEY` are not defined here because they are protected variables for the GitLab project. -- ***safety*** - Example for a vulnerability scan with [safety](https://github.com/pyupio/safety). Output will be stored in JSON format (`safety.json`). +- ***trivy*** - Example for a vulnerability scan with [trivy](https://github.com/aquasecurity/trivy). Output will be stored in JSON format (`trivy.json`). - ***cloc*** - Example how to calculate the lines of code with [cloc](https://github.com/AlDanial/cloc). Output will be stored in JSON format (`cloc.json`). -- ***upload_safety*** - This step will be executed after the `safety` step, gets its output file and sets some variables specific for this step. Then the script to import the findings from this scan is executed. +- ***upload_trivy*** - This step will be executed after the `trivy` step, gets its output file and sets some variables specific for this step. Then the script to import the findings from this scan is executed. - ***upload_cloc*** - This step will be executed after the `cloc` step, gets its output file and sets some variables specific for this step. Then the script to import the language data is executed. Another example, showing how to use `dd-import` within a GitHub Action, can be found in [dd-import_example.yml](.github/workflows/dd-import_example.yml). diff --git a/dd_import/dd_api.py b/dd_import/dd_api.py index ac924d1..82e0f47 100644 --- a/dd_import/dd_api.py +++ b/dd_import/dd_api.py @@ -165,6 +165,8 @@ def reimport_scan(self, test): payload['version'] = self.environment.version if self.environment.endpoint_id is not None: payload['endpoint_to_add'] = int(self.environment.endpoint_id) + if self.environment.service is not None: + payload['service'] = self.environment.service if self.environment.file_name is not None: files = {'file': (self.environment.file_name, diff --git a/dd_import/environment.py b/dd_import/environment.py index 88ae035..29b95fd 100644 --- a/dd_import/environment.py +++ b/dd_import/environment.py @@ -19,6 +19,7 @@ def __init__(self): self.close_old_findings = os.getenv('DD_CLOSE_OLD_FINDINGS', 'True').lower() in ['true'] self.version = os.getenv('DD_VERSION', None) self.endpoint_id = os.getenv('DD_ENDPOINT_ID', None) + self.service = os.getenv('DD_SERVICE', None) self.build_id = os.getenv('DD_BUILD_ID', None) self.commit_hash = os.getenv('DD_COMMIT_HASH', None) self.branch_tag = os.getenv('DD_BRANCH_TAG', None) @@ -55,6 +56,7 @@ def check_environment_reimport_findings(self): print('DD_CLOSE_OLD_FINDINGS: ', self.close_old_findings) print('DD_VERSION: ', self.version) print('DD_ENDPOINT_ID: ', self.endpoint_id) + print('DD_SERVICE: ', self.service) print('DD_BUILD_ID: ', self.build_id) print('DD_COMMIT_HASH: ', self.commit_hash) print('DD_BRANCH_TAG: ', self.branch_tag) diff --git a/setup.cfg b/setup.cfg index e3b496b..a54393c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = dd-import -version = 1.0.2 +version = 1.0.3 author = Stefan Fleckenstein author_email = stefan.fleckenstein@maibornwolff.de description = A utility to (re-)import findings and language data into DefectDojo diff --git a/unittests/test_api.py b/unittests/test_api.py index 192ce42..cd8c45e 100644 --- a/unittests/test_api.py +++ b/unittests/test_api.py @@ -351,7 +351,8 @@ def test_get_test_type_not_found(self, mockGet, mockEnv): 'DD_CLOSE_OLD_FINDINGS': 'true', 'DD_MINIMUM_SEVERITY': 'Info', 'DD_VERSION': 'version', - 'DD_ENDPOINT_ID': '6'}) + 'DD_ENDPOINT_ID': '6', + 'DD_SERVICE': 'service'}) def test_reimport_findings_without_file(self, mockPost, mockEnv): response = Mock(spec=Response) response.status_code = 200 @@ -370,7 +371,8 @@ def test_reimport_findings_without_file(self, mockPost, mockEnv): 'close_old_findings': True, 'minimum_severity': 'Info', 'version': 'version', - 'endpoint_to_add': 6 + 'endpoint_to_add': 6, + 'service': 'service' } mockPost.assert_called_once_with(url, headers=self.header_without_json, data=payload) response.raise_for_status.assert_called_once() diff --git a/unittests/test_environment.py b/unittests/test_environment.py index ce2b5bb..aa2ff9c 100644 --- a/unittests/test_environment.py +++ b/unittests/test_environment.py @@ -33,6 +33,7 @@ def test_check_environment_reimport_findings_empty(self): 'DD_CLOSE_OLD_FINDINGS': 'False', 'DD_VERSION': 'version', 'DD_ENDPOINT_ID': 'endpoint_id', + 'DD_SERVICE': 'service', 'DD_BUILD_ID': 'build_id', 'DD_COMMIT_HASH': 'commit_hash', 'DD_BRANCH_TAG': 'branch_tag'}) @@ -57,6 +58,7 @@ def test_check_environment_reimport_findings_complete(self): self.assertFalse(environment.close_old_findings) self.assertEqual(environment.version, 'version') self.assertEqual(environment.endpoint_id, 'endpoint_id') + self.assertEqual(environment.service, 'service') self.assertEqual(environment.build_id, 'build_id') self.assertEqual(environment.commit_hash, 'commit_hash') self.assertEqual(environment.branch_tag, 'branch_tag')