From c2ebdfd9ec8e04e5577cadb2bf6630b20c046b05 Mon Sep 17 00:00:00 2001 From: Umidjon Urunov <79094563+UmidjonUrunov@users.noreply.github.com> Date: Wed, 19 Jan 2022 10:30:59 +0100 Subject: [PATCH] feat(protecode): add versioning model (#3373) * changes to detectExec before master merge * changes for detectExecuteScan * self generated code added * fix syntax errors and update docu * added unit tests for fail and Group * fix failOn bug * add Groups as string array * add Groups as string array * tests and validation for groups, failOn * Updated docs and added more tests * documentation md files should not be changed * Handle merge conflicts from PR 1845 * fix merge errors * remove duplicate groups, merge error * adding buildCode and buildTool as params * switching build options * building maven modules * parameter correction * parameter correction * gnerate with new build parameter * adding comments * removing piper lib master and modifying goUtils to download 1.5.7 release * first cleaning then installing * multi module maven built * multi module maven built removing unwanted code * multi module maven built moving inside switch * testing * modifying the default use case to also call maven build * modifying the default use case to also call maven build wih -- * corrected maven build command * corrected maven build command with %v * skipping test runs * testing for MTA project with single pom * adding absolute path to m2 path * clean up * adding switch for mta and maven and removing env from containers * commiting changes for new detect step * correting log message * code clean up * unit tests changes to detectExecute * basic tests for new change * restoring piperGoUtils to download correct piper binary * code clean up * code clean up * protecodeExecuteScan :: versioning model draft - 1 * protecodeExecuteScan :: version model draft-2 * protecodeExecuteScan :: changing filename and version concatenation * protecodeExecuteScan :: update documentation * protecodeExecuteScan :: double URL encoding has been corrected & console messaging improved * protecodeExecuteScan :: fixed Go/generate validation fail * protecodeExecuteScan :: fixing failed unit tests * protecodeExecuteScan :: Version field added * protecodeExecuteScan :: Version field add => minor changes * protecodeExecuteScan :: Version field add => fixing tests Co-authored-by: D072410 Co-authored-by: Keshav Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com> --- cmd/protecodeExecuteScan.go | 42 ++++++++++++++++---- cmd/protecodeExecuteScan_generated.go | 35 +++++++++++++--- pkg/protecode/protecode.go | 32 +++++++++++---- pkg/protecode/protecode_test.go | 30 +++++++------- resources/metadata/protecodeExecuteScan.yaml | 35 ++++++++++++++-- 5 files changed, 135 insertions(+), 39 deletions(-) diff --git a/cmd/protecodeExecuteScan.go b/cmd/protecodeExecuteScan.go index 54947eb37..117c055f2 100644 --- a/cmd/protecodeExecuteScan.go +++ b/cmd/protecodeExecuteScan.go @@ -23,6 +23,7 @@ import ( "github.com/SAP/jenkins-library/pkg/protecode" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/SAP/jenkins-library/pkg/toolrecord" + "github.com/SAP/jenkins-library/pkg/versioning" ) const ( @@ -183,10 +184,14 @@ func executeProtecodeScan(influx *protecodeExecuteScanInflux, client protecode.P log.Entry().Infof("replaceProductID is not provided and automatic search starts from group: %v ... ", config.Group) // log.Entry().Debugf("[DEBUG] ===> ReplaceProductID hasn't provided and automatic search starts... ") productID = client.LoadExistingProduct(config.Group, fileName) - } - log.Entry().Infof("Automatic search completed and found following product id: %v", productID) - // log.Entry().Debugf("[DEBUG] ===> Returned productID: %v", productID) + if productID > 0 { + log.Entry().Infof("Automatic search completed and found following product id: %v", productID) + // log.Entry().Debugf("[DEBUG] ===> Returned productID: %v", productID) + } else { + log.Entry().Infof("Automatic search completed but not found any similar product scan, now starts new scan creation") + } + } // check if no existing is found productID = uploadScanOrDeclareFetch(*config, productID, client, fileName) @@ -363,9 +368,12 @@ func uploadScanOrDeclareFetch(config protecodeExecuteScanOptions, productID int, func uploadFile(config protecodeExecuteScanOptions, productID int, client protecode.Protecode, fileName string, replaceBinary bool) int { + // get calculated version for Version field + version := getProcessedVersion(&config) + if len(config.FetchURL) > 0 { log.Entry().Debugf("Declare fetch url %v", config.FetchURL) - resultData := client.DeclareFetchURL(config.CleanupMode, config.Group, config.FetchURL, productID, replaceBinary) + resultData := client.DeclareFetchURL(config.CleanupMode, config.Group, config.FetchURL, version, productID, replaceBinary) productID = resultData.Result.ProductID } else { log.Entry().Debugf("Upload file path: %v", config.FilePath) @@ -382,7 +390,7 @@ func uploadFile(config protecodeExecuteScanOptions, productID int, client protec combinedFileName = fmt.Sprintf("%v_%v", config.PullRequestName, fileName) } - resultData := client.UploadScanFile(config.CleanupMode, config.Group, pathToFile, combinedFileName, productID, replaceBinary) + resultData := client.UploadScanFile(config.CleanupMode, config.Group, pathToFile, combinedFileName, version, productID, replaceBinary) productID = resultData.Result.ProductID log.Entry().Debugf("[DEBUG] ===> uploadFile return FINAL product id: %v", productID) } @@ -429,6 +437,7 @@ func correctDockerConfigEnvVar(config *protecodeExecuteScanOptions) { } func getTarName(config *protecodeExecuteScanOptions) string { + // remove original version fileName := strings.TrimSuffix(config.ScanImage, ":"+config.Version) // remove sha digest if exists @@ -436,14 +445,33 @@ func getTarName(config *protecodeExecuteScanOptions) string { if index := strings.Index(fileName, sha256); index > -1 { fileName = fileName[:index] } - // append trimmed version - if version := handleArtifactVersion(config.Version); len(version) > 0 { + + version := getProcessedVersion(config) + if len(version) > 0 { fileName = fileName + "_" + version } + fileName = strings.ReplaceAll(fileName, "/", "_") + return fileName + ".tar" } +// Calculate version based on versioning model and artifact version or return custom scan version provided by user +func getProcessedVersion(config *protecodeExecuteScanOptions) string { + processedVersion := config.CustomScanVersion + if len(processedVersion) > 0 { + log.Entry().Infof("Using custom version: %v", processedVersion) + } else { + if len(config.VersioningModel) > 0 { + processedVersion = versioning.ApplyVersioningModel(config.VersioningModel, config.Version) + } else { + // By default 'major' if not provided + processedVersion = versioning.ApplyVersioningModel("major", config.Version) + } + } + return processedVersion +} + // create toolrecord file for protecode // todo: check if group and product names can be retrieved func createToolRecordProtecode(workspace string, config *protecodeExecuteScanOptions, productID int, webuiURL string) (string, error) { diff --git a/cmd/protecodeExecuteScan_generated.go b/cmd/protecodeExecuteScan_generated.go index a5e0ad847..7b8f7382d 100644 --- a/cmd/protecodeExecuteScan_generated.go +++ b/cmd/protecodeExecuteScan_generated.go @@ -36,6 +36,8 @@ type protecodeExecuteScanOptions struct { Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` Version string `json:"version,omitempty"` + CustomScanVersion string `json:"customScanVersion,omitempty"` + VersioningModel string `json:"versioningModel,omitempty" validate:"possible-values=major major-minor semantic full"` PullRequestName string `json:"pullRequestName,omitempty"` } @@ -90,7 +92,7 @@ func (i *protecodeExecuteScanInflux) persist(path, resourceName string) { } } -// ProtecodeExecuteScanCommand Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family. +// ProtecodeExecuteScanCommand Black Duck Binary Analysis (BDBA), previously known as Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family. func ProtecodeExecuteScanCommand() *cobra.Command { const STEP_NAME = "protecodeExecuteScan" @@ -104,11 +106,12 @@ func ProtecodeExecuteScanCommand() *cobra.Command { var createProtecodeExecuteScanCmd = &cobra.Command{ Use: STEP_NAME, - Short: "Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family.", - Long: `Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family. + Short: "Black Duck Binary Analysis (BDBA), previously known as Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family.", + Long: `Black Duck Binary Analysis (previously known as Protecode) is an Open Source Vulnerability Scan tool which provides the composition of Open Source components in a product along with Security information (no license info is provided). +BDBA (Protecode) uses a combination of static binary analysis techniques to X-ray the provided software package to identify third-party software components and their exact versions with a high level of confidence. Methods range from simple string matching to proprietary patent-pending techniques. !!! hint "Auditing findings (Triaging)" - Triaging is now supported by the Protecode backend and also Piper does consider this information during the analysis of the scan results though product versions are not supported by Protecode. Therefore please make sure that the ` + "`" + `fileName` + "`" + ` you are providing does either contain a stable version or that it does not contain one at all. By ensuring that you are able to triage CVEs globally on the upload file's name without affecting any other artifacts scanned in the same Protecode group and as such triaged vulnerabilities will be considered during the next scan and will not fail the build anymore.`, + Triaging is now supported by the BDBA (Protecode) backend and also Piper does consider this information during the analysis of the scan results though product versions are not supported by BDBA (Protecode). Therefore please make sure that the ` + "`" + `fileName` + "`" + ` you are providing does either contain a stable version or that it does not contain one at all. By ensuring that you are able to triage CVEs globally on the upload file's name without affecting any other artifacts scanned in the same BDBA (Protecode) group and as such triaged vulnerabilities will be considered during the next scan and will not fail the build anymore.`, PreRunE: func(cmd *cobra.Command, _ []string) error { startTime = time.Now() log.SetStepName(STEP_NAME) @@ -189,7 +192,7 @@ func ProtecodeExecuteScanCommand() *cobra.Command { func addProtecodeExecuteScanFlags(cmd *cobra.Command, stepConfig *protecodeExecuteScanOptions) { cmd.Flags().StringVar(&stepConfig.ExcludeCVEs, "excludeCVEs", ``, "DEPRECATED: Do use triaging within the Protecode UI instead") cmd.Flags().BoolVar(&stepConfig.FailOnSevereVulnerabilities, "failOnSevereVulnerabilities", true, "Whether to fail the job on severe vulnerabilties or not") - cmd.Flags().StringVar(&stepConfig.ScanImage, "scanImage", os.Getenv("PIPER_scanImage"), "The reference to the docker image to scan with Protecode") + cmd.Flags().StringVar(&stepConfig.ScanImage, "scanImage", os.Getenv("PIPER_scanImage"), "The reference to the docker image to scan with Protecode. Note: If possible please also check [fetchUrl](https://www.project-piper.io/steps/protecodeExecuteScan/#fetchurl) parameter, which might help you to optimize upload time.") cmd.Flags().StringVar(&stepConfig.DockerRegistryURL, "dockerRegistryUrl", os.Getenv("PIPER_dockerRegistryUrl"), "The reference to the docker registry to scan with Protecode") cmd.Flags().StringVar(&stepConfig.DockerConfigJSON, "dockerConfigJSON", os.Getenv("PIPER_dockerConfigJSON"), "Path to the file `.docker/config.json` - this is typically provided by your CI/CD system. You can find more details about the Docker credentials in the [Docker documentation](https://docs.docker.com/engine/reference/commandline/login/).") cmd.Flags().StringVar(&stepConfig.CleanupMode, "cleanupMode", `binary`, "Decides which parts are removed from the Protecode backend after the scan") @@ -205,6 +208,8 @@ func addProtecodeExecuteScanFlags(cmd *cobra.Command, stepConfig *protecodeExecu cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "User which is used for the protecode scan") cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password which is used for the user") cmd.Flags().StringVar(&stepConfig.Version, "version", os.Getenv("PIPER_version"), "The version of the artifact to allow identification in protecode backend") + cmd.Flags().StringVar(&stepConfig.CustomScanVersion, "customScanVersion", os.Getenv("PIPER_customScanVersion"), "A custom version used along with the uploaded scan results.") + cmd.Flags().StringVar(&stepConfig.VersioningModel, "versioningModel", `major`, "The versioning model used for result reporting (based on the artifact version). Example 1.2.3 using `major` will result in version 1") cmd.Flags().StringVar(&stepConfig.PullRequestName, "pullRequestName", os.Getenv("PIPER_pullRequestName"), "The name of the pull request") cmd.MarkFlagRequired("serverUrl") @@ -219,7 +224,7 @@ func protecodeExecuteScanMetadata() config.StepData { Metadata: config.StepMetadata{ Name: "protecodeExecuteScan", Aliases: []config.Alias{}, - Description: "Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family.", + Description: "Black Duck Binary Analysis (BDBA), previously known as Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family.", }, Spec: config.StepSpec{ Inputs: config.StepInputs{ @@ -445,6 +450,24 @@ func protecodeExecuteScanMetadata() config.StepData { Aliases: []config.Alias{{Name: "artifactVersion", Deprecated: true}}, Default: os.Getenv("PIPER_version"), }, + { + Name: "customScanVersion", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"GENERAL", "STAGES", "STEPS", "PARAMETERS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: os.Getenv("PIPER_customScanVersion"), + }, + { + Name: "versioningModel", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "GENERAL", "STAGES", "STEPS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: `major`, + }, { Name: "pullRequestName", ResourceRef: []config.ResourceReference{}, diff --git a/pkg/protecode/protecode.go b/pkg/protecode/protecode.go index 04211f7f8..37a0fb9c9 100644 --- a/pkg/protecode/protecode.go +++ b/pkg/protecode/protecode.go @@ -144,9 +144,9 @@ func (pc *Protecode) createURL(path string, pValue string, fParam string) string // Prepare Query Parameters if len(fParam) > 0 { - encodedFParam := url.QueryEscape(fParam) + // encodedFParam := url.QueryEscape(fParam) params := url.Values{} - params.Add("q", fmt.Sprintf("file:%v", encodedFParam)) + params.Add("q", fmt.Sprintf("file:%v", fParam)) // Add Query Parameters to the URL protecodeURL.RawQuery = params.Encode() // Escape Query Parameters @@ -311,16 +311,24 @@ func (pc *Protecode) LoadReport(reportFileName string, productID int) *io.ReadCl } // UploadScanFile upload the scan file to the protecode server -func (pc *Protecode) UploadScanFile(cleanupMode, group, filePath, fileName string, productID int, replaceBinary bool) *ResultData { +func (pc *Protecode) UploadScanFile(cleanupMode, group, filePath, fileName, version string, productID int, replaceBinary bool) *ResultData { log.Entry().Debugf("[DEBUG] ===> UploadScanFile started.....") deleteBinary := (cleanupMode == "binary" || cleanupMode == "complete") var headers = make(map[string][]string) - if replaceBinary { - headers = map[string][]string{"Group": {group}, "Replace": {fmt.Sprintf("%v", productID)}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}} + if (replaceBinary) && (version != "") { + log.Entry().Debugf("[DEBUG] ===> replaceBinary && version != empty ") + headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Replace": {fmt.Sprintf("%v", productID)}, "Version": {version}} + } else if replaceBinary { + log.Entry().Debugf("[DEBUG] ===> replaceBinary") + headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Replace": {fmt.Sprintf("%v", productID)}} + } else if version != "" { + log.Entry().Debugf("[DEBUG] ===> version != empty ") + headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Version": {version}} } else { + log.Entry().Debugf("[DEBUG] ===> replaceBinary is false and version == empty") headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}} } @@ -358,14 +366,22 @@ func (pc *Protecode) UploadScanFile(cleanupMode, group, filePath, fileName strin } // DeclareFetchURL configures the fetch url for the protecode scan -func (pc *Protecode) DeclareFetchURL(cleanupMode, group, fetchURL string, productID int, replaceBinary bool) *ResultData { +func (pc *Protecode) DeclareFetchURL(cleanupMode, group, fetchURL, version string, productID int, replaceBinary bool) *ResultData { deleteBinary := (cleanupMode == "binary" || cleanupMode == "complete") var headers = make(map[string][]string) - if replaceBinary { - headers = map[string][]string{"Group": {group}, "Replace": {fmt.Sprintf("%v", productID)}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Url": {fetchURL}, "Content-Type": {"application/json"}} + if (replaceBinary) && (version != "") { + log.Entry().Debugf("[DEBUG][FETCH_URL] ===> replaceBinary && version != empty ") + headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Replace": {fmt.Sprintf("%v", productID)}, "Version": {version}, "Url": {fetchURL}, "Content-Type": {"application/json"}} + } else if replaceBinary { + log.Entry().Debugf("[DEBUG][FETCH_URL] ===> replaceBinary") + headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Replace": {fmt.Sprintf("%v", productID)}, "Url": {fetchURL}, "Content-Type": {"application/json"}} + } else if version != "" { + log.Entry().Debugf("[DEBUG][FETCH_URL] ===> version != empty ") + headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Version": {version}, "Url": {fetchURL}, "Content-Type": {"application/json"}} } else { + log.Entry().Debugf("[DEBUG][FETCH_URL] ===> replaceBinary is false and version == empty") headers = map[string][]string{"Group": {group}, "Delete-Binary": {fmt.Sprintf("%v", deleteBinary)}, "Url": {fetchURL}, "Content-Type": {"application/json"}} } diff --git a/pkg/protecode/protecode_test.go b/pkg/protecode/protecode_test.go index 6897c9846..7ac489bde 100644 --- a/pkg/protecode/protecode_test.go +++ b/pkg/protecode/protecode_test.go @@ -313,22 +313,23 @@ func TestDeclareFetchURLSuccess(t *testing.T) { cleanupMode string protecodeGroup string fetchURL string + version string productID int replaceBinary bool want int }{ - {"binary", "group1", "/api/fetch/", 1, true, 111}, - {"binary", "group1", "/api/fetch/", -1, true, 111}, - {"binary", "group1", "/api/fetch/", 0, true, 111}, + {"binary", "group1", "/api/fetch/", "", 1, true, 111}, + {"binary", "group1", "/api/fetch/", "custom-test-version", -1, true, 111}, + {"binary", "group1", "/api/fetch/", "1.2.3", 0, true, 111}, - {"binary", "group1", "/api/fetch/", 1, false, 111}, - {"binary", "group1", "/api/fetch/", -1, false, 111}, - {"binary", "group1", "/api/fetch/", 0, false, 111}, + {"binary", "group1", "/api/fetch/", "", 1, false, 111}, + {"binary", "group1", "/api/fetch/", "custom-test-version", -1, false, 111}, + {"binary", "group1", "/api/fetch/", "1.2.3", 0, false, 111}, } for _, c := range cases { // pc.DeclareFetchURL(c.cleanupMode, c.protecodeGroup, c.fetchURL) - got := pc.DeclareFetchURL(c.cleanupMode, c.protecodeGroup, c.fetchURL, c.productID, c.replaceBinary) + got := pc.DeclareFetchURL(c.cleanupMode, c.protecodeGroup, c.fetchURL, c.version, c.productID, c.replaceBinary) assert.Equal(t, requestURI, "/api/fetch/") assert.Equal(t, got.Result.ProductID, c.want) @@ -421,24 +422,25 @@ func TestUploadScanFileSuccess(t *testing.T) { cleanupMode string protecodeGroup string filePath string + version string productID int replaceBinary bool want int }{ - {"binary", "group1", testFile.Name(), 1, true, 1}, - {"binary", "group1", testFile.Name(), 0, true, 0}, - {"binary", "group1", testFile.Name(), -1, true, -1}, + {"binary", "group1", testFile.Name(), "", 1, true, 1}, + {"binary", "group1", testFile.Name(), "custom-test-version", 0, true, 0}, + {"binary", "group1", testFile.Name(), "1.2.3", -1, true, -1}, - {"binary", "group1", testFile.Name(), 1, false, 112}, - {"binary", "group1", testFile.Name(), 0, false, 112}, - {"binary", "group1", testFile.Name(), -1, false, 112}, + {"binary", "group1", testFile.Name(), "", 1, false, 112}, + {"binary", "group1", testFile.Name(), "custom-test-version", 0, false, 112}, + {"binary", "group1", testFile.Name(), "1.2.3", -1, false, 112}, // {"binary", "group1", testFile.Name(), "/api/upload/dummy"}, // {"Test", "group2", testFile.Name(), "/api/upload/dummy"}, } for _, c := range cases { - got := pc.UploadScanFile(c.cleanupMode, c.protecodeGroup, c.filePath, "dummy.tar", c.productID, c.replaceBinary) + got := pc.UploadScanFile(c.cleanupMode, c.protecodeGroup, c.filePath, "dummy.tar", c.version, c.productID, c.replaceBinary) assert.Equal(t, requestURI, "/api/upload/dummy.tar") assert.Contains(t, passedHeaders, "Group") diff --git a/resources/metadata/protecodeExecuteScan.yaml b/resources/metadata/protecodeExecuteScan.yaml index 7a888d458..14a963506 100644 --- a/resources/metadata/protecodeExecuteScan.yaml +++ b/resources/metadata/protecodeExecuteScan.yaml @@ -1,11 +1,12 @@ metadata: name: protecodeExecuteScan - description: Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family. + description: Black Duck Binary Analysis (BDBA), previously known as Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family. longDescription: |- - Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family. + Black Duck Binary Analysis (previously known as Protecode) is an Open Source Vulnerability Scan tool which provides the composition of Open Source components in a product along with Security information (no license info is provided). + BDBA (Protecode) uses a combination of static binary analysis techniques to X-ray the provided software package to identify third-party software components and their exact versions with a high level of confidence. Methods range from simple string matching to proprietary patent-pending techniques. !!! hint "Auditing findings (Triaging)" - Triaging is now supported by the Protecode backend and also Piper does consider this information during the analysis of the scan results though product versions are not supported by Protecode. Therefore please make sure that the `fileName` you are providing does either contain a stable version or that it does not contain one at all. By ensuring that you are able to triage CVEs globally on the upload file's name without affecting any other artifacts scanned in the same Protecode group and as such triaged vulnerabilities will be considered during the next scan and will not fail the build anymore. + Triaging is now supported by the BDBA (Protecode) backend and also Piper does consider this information during the analysis of the scan results though product versions are not supported by BDBA (Protecode). Therefore please make sure that the `fileName` you are providing does either contain a stable version or that it does not contain one at all. By ensuring that you are able to triage CVEs globally on the upload file's name without affecting any other artifacts scanned in the same BDBA (Protecode) group and as such triaged vulnerabilities will be considered during the next scan and will not fail the build anymore. spec: inputs: secrets: @@ -43,7 +44,7 @@ spec: aliases: - name: dockerImage type: string - description: The reference to the docker image to scan with Protecode + description: "The reference to the docker image to scan with Protecode. Note: If possible please also check [fetchUrl](https://www.project-piper.io/steps/protecodeExecuteScan/#fetchurl) parameter, which might help you to optimize upload time." resourceRef: - name: commonPipelineEnvironment param: container/imageNameTag @@ -218,6 +219,32 @@ spec: - PARAMETERS - STAGES - STEPS + - name: customScanVersion + type: string + description: "A custom version used along with the uploaded scan results." + longDescription: |- + Defines a custom version for the BDBA scan which deviates from the typical versioning pattern using [`version`](#version) and [`versioningModel`](#versioningModel). + It allows to set non-numeric versions as well and supersedes the value of [`version`](#version) which is calculated automatically. + The parameter is also used by other scan steps (e.g. Fortify, Sonar, WhiteSource) and thus allows a common custom version across scan tools. + scope: [GENERAL, STAGES, STEPS, PARAMETERS] + - name: versioningModel + type: string + description: The versioning model used for result reporting (based on the artifact version). Example 1.2.3 using `major` will result in version 1 + longDescription: |- + The versioning model used for result reporting (based on the artifact version). + For example: the version 1.2.3 of the artifact will result in a version 1 to report into, when `versioningModel: major` is used and will result in a version 1.2 when `versioningModel: major-minor` is used. + Recommendation for a Continuous Delivery process is to use `versioningModel: major`. + scope: + - PARAMETERS + - GENERAL + - STAGES + - STEPS + default: "major" + possibleValues: + - major + - major-minor + - semantic + - full - name: pullRequestName type: string description: The name of the pull request