1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-02-09 13:47:31 +02:00

feat (protecodeExecuteScan) enhancing protecode step with registry credentials (#4378)

* enhancing protecode with registry credentials

* Use protecodeUtils instead of separate package

* Add target path for docker config to be created

* Fix tests

* Fix build flags

---------

Co-authored-by: Vyacheslav Starostin <vyacheslav.starostin@sap.com>
This commit is contained in:
Anil Keshav 2023-06-14 09:11:33 +02:00 committed by GitHub
parent 97495fd18b
commit 39d52a2123
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 7 deletions

View File

@ -15,6 +15,7 @@ import (
"github.com/pkg/errors"
"github.com/SAP/jenkins-library/pkg/command"
"github.com/SAP/jenkins-library/pkg/docker"
piperDocker "github.com/SAP/jenkins-library/pkg/docker"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
@ -25,9 +26,10 @@ import (
)
const (
webReportPath = "%s/#/product/%v/"
scanResultFile = "protecodescan_vulns.json"
stepResultFile = "protecodeExecuteScan.json"
webReportPath = "%s/#/product/%v/"
scanResultFile = "protecodescan_vulns.json"
stepResultFile = "protecodeExecuteScan.json"
dockerConfigFile = ".pipeline/docker/config.json"
)
type protecodeUtils interface {
@ -72,7 +74,9 @@ func runProtecodeScan(config *protecodeExecuteScanOptions, influx *protecodeExec
return err
}
correctDockerConfigEnvVar(config)
if err := correctDockerConfigEnvVar(config, utils); err != nil {
return err
}
var fileName, filePath string
var err error
@ -372,8 +376,18 @@ func uploadFile(utils protecodeUtils, config protecodeExecuteScanOptions, produc
return productID
}
func correctDockerConfigEnvVar(config *protecodeExecuteScanOptions) {
func correctDockerConfigEnvVar(config *protecodeExecuteScanOptions, utils protecodeUtils) error {
var err error
path := config.DockerConfigJSON
if len(config.DockerConfigJSON) > 0 && len(config.DockerRegistryURL) > 0 && len(config.ContainerRegistryPassword) > 0 && len(config.ContainerRegistryUser) > 0 {
path, err = docker.CreateDockerConfigJSON(config.DockerRegistryURL, config.ContainerRegistryUser, config.ContainerRegistryPassword, dockerConfigFile, config.DockerConfigJSON, utils)
}
if err != nil {
return errors.Wrapf(err, "failed to create / update docker config json file")
}
if len(path) > 0 {
log.Entry().Infof("Docker credentials configuration: %v", path)
path, _ := filepath.Abs(path)
@ -383,6 +397,7 @@ func correctDockerConfigEnvVar(config *protecodeExecuteScanOptions) {
} else {
log.Entry().Info("Docker credentials configuration: NONE")
}
return nil
}
// Calculate version based on versioning model and artifact version or return custom scan version provided by user

View File

@ -26,6 +26,8 @@ type protecodeExecuteScanOptions struct {
FailOnSevereVulnerabilities bool `json:"failOnSevereVulnerabilities,omitempty"`
ScanImage string `json:"scanImage,omitempty"`
DockerRegistryURL string `json:"dockerRegistryUrl,omitempty"`
ContainerRegistryPassword string `json:"containerRegistryPassword,omitempty"`
ContainerRegistryUser string `json:"containerRegistryUser,omitempty"`
DockerConfigJSON string `json:"dockerConfigJSON,omitempty"`
CleanupMode string `json:"cleanupMode,omitempty" validate:"possible-values=none binary complete"`
FilePath string `json:"filePath,omitempty"`
@ -173,6 +175,8 @@ BDBA (Protecode) uses a combination of static binary analysis techniques to X-ra
log.SetErrorCategory(log.ErrorConfiguration)
return err
}
log.RegisterSecret(stepConfig.ContainerRegistryPassword)
log.RegisterSecret(stepConfig.ContainerRegistryUser)
log.RegisterSecret(stepConfig.DockerConfigJSON)
log.RegisterSecret(stepConfig.Username)
log.RegisterSecret(stepConfig.Password)
@ -245,6 +249,8 @@ func addProtecodeExecuteScanFlags(cmd *cobra.Command, stepConfig *protecodeExecu
cmd.Flags().BoolVar(&stepConfig.FailOnSevereVulnerabilities, "failOnSevereVulnerabilities", true, "Whether to fail the step 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. 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.ContainerRegistryPassword, "containerRegistryPassword", os.Getenv("PIPER_containerRegistryPassword"), "For `buildTool: docker`: Password for container registry access - typically provided by the CI/CD environment.")
cmd.Flags().StringVar(&stepConfig.ContainerRegistryUser, "containerRegistryUser", os.Getenv("PIPER_containerRegistryUser"), "For `buildTool: docker`: Username for container registry access - typically provided by the CI/CD environment.")
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")
cmd.Flags().StringVar(&stepConfig.FilePath, "filePath", os.Getenv("PIPER_filePath"), "The path to the file from local workspace to scan with Protecode")
@ -332,6 +338,44 @@ func protecodeExecuteScanMetadata() config.StepData {
Aliases: []config.Alias{},
Default: os.Getenv("PIPER_dockerRegistryUrl"),
},
{
Name: "containerRegistryPassword",
ResourceRef: []config.ResourceReference{
{
Name: "commonPipelineEnvironment",
Param: "container/repositoryPassword",
},
{
Name: "commonPipelineEnvironment",
Param: "custom/repositoryPassword",
},
},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: false,
Aliases: []config.Alias{},
Default: os.Getenv("PIPER_containerRegistryPassword"),
},
{
Name: "containerRegistryUser",
ResourceRef: []config.ResourceReference{
{
Name: "commonPipelineEnvironment",
Param: "container/repositoryUsername",
},
{
Name: "commonPipelineEnvironment",
Param: "custom/repositoryUsername",
},
},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: false,
Aliases: []config.Alias{},
Default: os.Getenv("PIPER_containerRegistryUser"),
},
{
Name: "dockerConfigJSON",
ResourceRef: []config.ResourceReference{

View File

@ -348,6 +348,11 @@ func TestExecuteProtecodeScan(t *testing.T) {
}
func TestCorrectDockerConfigEnvVar(t *testing.T) {
utils := protecodeTestUtilsBundle{
FilesMock: &mock.FilesMock{},
DownloadMock: &mock.DownloadMock{},
}
t.Run("with credentials", func(t *testing.T) {
// init
testDirectory := t.TempDir()
@ -366,7 +371,7 @@ func TestCorrectDockerConfigEnvVar(t *testing.T) {
resetValue := os.Getenv("DOCKER_CONFIG")
defer os.Setenv("DOCKER_CONFIG", resetValue)
// test
correctDockerConfigEnvVar(&protecodeExecuteScanOptions{DockerConfigJSON: dockerConfigFile})
correctDockerConfigEnvVar(&protecodeExecuteScanOptions{DockerConfigJSON: dockerConfigFile}, utils)
// assert
absolutePath, _ := filepath.Abs(dockerConfigDir)
assert.Equal(t, absolutePath, os.Getenv("DOCKER_CONFIG"))
@ -376,7 +381,7 @@ func TestCorrectDockerConfigEnvVar(t *testing.T) {
resetValue := os.Getenv("DOCKER_CONFIG")
defer os.Setenv("DOCKER_CONFIG", resetValue)
// test
correctDockerConfigEnvVar(&protecodeExecuteScanOptions{})
correctDockerConfigEnvVar(&protecodeExecuteScanOptions{}, utils)
// assert
assert.Equal(t, resetValue, os.Getenv("DOCKER_CONFIG"))
})

View File

@ -67,6 +67,32 @@ spec:
- PARAMETERS
- STAGES
- STEPS
- name: containerRegistryPassword
description: "For `buildTool: docker`: Password for container registry access - typically provided by the CI/CD environment."
type: string
scope:
- PARAMETERS
- STAGES
- STEPS
secret: true
resourceRef:
- name: commonPipelineEnvironment
param: container/repositoryPassword
- name: commonPipelineEnvironment
param: custom/repositoryPassword
- name: containerRegistryUser
description: "For `buildTool: docker`: Username for container registry access - typically provided by the CI/CD environment."
type: string
scope:
- PARAMETERS
- STAGES
- STEPS
secret: true
resourceRef:
- name: commonPipelineEnvironment
param: container/repositoryUsername
- name: commonPipelineEnvironment
param: custom/repositoryUsername
- name: dockerConfigJSON
type: string
description: 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/).