You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	feat(WhiteSource): consume credentials from cpe (#3206)
* feat: func for Docker config.json Provide re-use function to create/update Docker conifg.json * add comment * update WhiteSource step * fixes and additional tests
This commit is contained in:
		| @@ -48,7 +48,7 @@ type whitesource interface { | ||||
|  | ||||
| type whitesourceUtils interface { | ||||
| 	ws.Utils | ||||
| 	DirExists(path string) (bool, error) | ||||
| 	piperutils.FileUtils | ||||
| 	GetArtifactCoordinates(buildTool, buildDescriptorFile string, | ||||
| 		options *versioning.Options) (versioning.Coordinates, error) | ||||
|  | ||||
| @@ -162,7 +162,7 @@ func runWhitesourceExecuteScan(config *ScanOptions, scan *ws.Scan, utils whiteso | ||||
| } | ||||
|  | ||||
| func runWhitesourceScan(config *ScanOptions, scan *ws.Scan, utils whitesourceUtils, sys whitesource, commonPipelineEnvironment *whitesourceExecuteScanCommonPipelineEnvironment, influx *whitesourceExecuteScanInflux) error { | ||||
| 	correctWhitesourceDockerConfigEnvVar(config) | ||||
| 	correctWhitesourceDockerConfigEnvVar(config, utils) | ||||
|  | ||||
| 	// Download Docker image for container scan | ||||
| 	// ToDo: move it to improve testability | ||||
| @@ -213,11 +213,18 @@ func runWhitesourceScan(config *ScanOptions, scan *ws.Scan, utils whitesourceUti | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func correctWhitesourceDockerConfigEnvVar(config *ScanOptions) { | ||||
| func correctWhitesourceDockerConfigEnvVar(config *ScanOptions, utils whitesourceUtils) { | ||||
| 	path := config.DockerConfigJSON | ||||
| 	if len(path) > 0 { | ||||
| 		log.Entry().Infof("Docker credentials configuration: %v", path) | ||||
| 		path, _ := filepath.Abs(path) | ||||
| 		if len(config.ScanImageRegistryURL) > 0 && len(config.ContainerRegistryUser) > 0 && len(config.ContainerRegistryPassword) > 0 { | ||||
| 			var err error | ||||
| 			path, err = piperDocker.CreateDockerConfigJSON(config.ScanImageRegistryURL, config.ContainerRegistryUser, config.ContainerRegistryPassword, "", config.DockerConfigJSON, utils) | ||||
| 			if err != nil { | ||||
| 				log.Entry().Warningf("failed to update Docker config.json: %v", err) | ||||
| 			} | ||||
| 		} | ||||
| 		path, _ := utils.Abs(path) | ||||
| 		// use parent directory | ||||
| 		path = filepath.Dir(path) | ||||
| 		os.Setenv("DOCKER_CONFIG", path) | ||||
|   | ||||
| @@ -27,6 +27,8 @@ type whitesourceExecuteScanOptions struct { | ||||
| 	BuildDescriptorFile                  string   `json:"buildDescriptorFile,omitempty"` | ||||
| 	BuildTool                            string   `json:"buildTool,omitempty"` | ||||
| 	ConfigFilePath                       string   `json:"configFilePath,omitempty"` | ||||
| 	ContainerRegistryPassword            string   `json:"containerRegistryPassword,omitempty"` | ||||
| 	ContainerRegistryUser                string   `json:"containerRegistryUser,omitempty"` | ||||
| 	CreateProductFromPipeline            bool     `json:"createProductFromPipeline,omitempty"` | ||||
| 	CustomScanVersion                    string   `json:"customScanVersion,omitempty"` | ||||
| 	CvssSeverityLimit                    string   `json:"cvssSeverityLimit,omitempty"` | ||||
| @@ -177,6 +179,8 @@ The step uses the so-called WhiteSource Unified Agent. For details please refer | ||||
| 				log.SetErrorCategory(log.ErrorConfiguration) | ||||
| 				return err | ||||
| 			} | ||||
| 			log.RegisterSecret(stepConfig.ContainerRegistryPassword) | ||||
| 			log.RegisterSecret(stepConfig.ContainerRegistryUser) | ||||
| 			log.RegisterSecret(stepConfig.DockerConfigJSON) | ||||
| 			log.RegisterSecret(stepConfig.OrgToken) | ||||
| 			log.RegisterSecret(stepConfig.UserToken) | ||||
| @@ -246,6 +250,8 @@ func addWhitesourceExecuteScanFlags(cmd *cobra.Command, stepConfig *whitesourceE | ||||
| 	cmd.Flags().StringVar(&stepConfig.BuildDescriptorFile, "buildDescriptorFile", os.Getenv("PIPER_buildDescriptorFile"), "Explicit path to the build descriptor file.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.BuildTool, "buildTool", os.Getenv("PIPER_buildTool"), "Defines the tool which is used for building the artifact.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.ConfigFilePath, "configFilePath", `./wss-unified-agent.config`, "Explicit path to the WhiteSource Unified Agent configuration file.") | ||||
| 	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().BoolVar(&stepConfig.CreateProductFromPipeline, "createProductFromPipeline", true, "Whether to create the related WhiteSource product on the fly based on the supplied pipeline configuration.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CustomScanVersion, "customScanVersion", os.Getenv("PIPER_customScanVersion"), "Custom version of the WhiteSource project used as source.") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CvssSeverityLimit, "cvssSeverityLimit", `-1`, "Limit of tolerable CVSS v3 score upon assessment and in consequence fails the build.") | ||||
| @@ -392,6 +398,34 @@ func whitesourceExecuteScanMetadata() config.StepData { | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     `./wss-unified-agent.config`, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name: "containerRegistryPassword", | ||||
| 						ResourceRef: []config.ResourceReference{ | ||||
| 							{ | ||||
| 								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: "custom/repositoryUsername", | ||||
| 							}, | ||||
| 						}, | ||||
| 						Scope:     []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:      "string", | ||||
| 						Mandatory: false, | ||||
| 						Aliases:   []config.Alias{}, | ||||
| 						Default:   os.Getenv("PIPER_containerRegistryUser"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "createProductFromPipeline", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
|   | ||||
| @@ -2,7 +2,6 @@ package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| @@ -15,7 +14,6 @@ import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/versioning" | ||||
| 	ws "github.com/SAP/jenkins-library/pkg/whitesource" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
|  | ||||
| type whitesourceUtilsMock struct { | ||||
| @@ -135,33 +133,48 @@ func TestRunWhitesourceExecuteScan(t *testing.T) { | ||||
| func TestCorrectWhitesourceDockerConfigEnvVar(t *testing.T) { | ||||
| 	t.Run("with credentials", func(t *testing.T) { | ||||
| 		// init | ||||
| 		testDirectory, _ := ioutil.TempDir(".", "") | ||||
| 		require.DirExists(t, testDirectory) | ||||
| 		defer os.RemoveAll(testDirectory) | ||||
| 		utilsMock := newWhitesourceUtilsMock() | ||||
| 		utilsMock.CurrentDir = "/tmp/test" | ||||
|  | ||||
| 		dockerConfigDir := filepath.Join(testDirectory, "myConfig") | ||||
| 		os.Mkdir(dockerConfigDir, 0755) | ||||
| 		require.DirExists(t, dockerConfigDir) | ||||
|  | ||||
| 		dockerConfigFile := filepath.Join(dockerConfigDir, "docker.json") | ||||
| 		file, _ := os.Create(dockerConfigFile) | ||||
| 		defer file.Close() | ||||
| 		require.FileExists(t, dockerConfigFile) | ||||
| 		dockerConfigFile := "myConfig/docker.json" | ||||
| 		utilsMock.AddFile(dockerConfigFile, []byte("{}")) | ||||
|  | ||||
| 		resetValue := os.Getenv("DOCKER_CONFIG") | ||||
| 		defer os.Setenv("DOCKER_CONFIG", resetValue) | ||||
|  | ||||
| 		// test | ||||
| 		correctWhitesourceDockerConfigEnvVar(&ScanOptions{DockerConfigJSON: dockerConfigFile}) | ||||
| 		correctWhitesourceDockerConfigEnvVar(&ScanOptions{DockerConfigJSON: dockerConfigFile}, utilsMock) | ||||
| 		// assert | ||||
| 		absolutePath, _ := filepath.Abs(dockerConfigDir) | ||||
| 		absolutePath, _ := utilsMock.Abs(filepath.Dir(dockerConfigFile)) | ||||
| 		assert.Equal(t, absolutePath, os.Getenv("DOCKER_CONFIG")) | ||||
| 	}) | ||||
| 	t.Run("with added credentials", func(t *testing.T) { | ||||
| 		// init | ||||
| 		utilsMock := newWhitesourceUtilsMock() | ||||
| 		utilsMock.CurrentDir = "/tmp/test" | ||||
|  | ||||
| 		dockerConfigFile := "myConfig/docker.json" | ||||
| 		utilsMock.AddFile(dockerConfigFile, []byte("{}")) | ||||
|  | ||||
| 		resetValue := os.Getenv("DOCKER_CONFIG") | ||||
| 		defer os.Setenv("DOCKER_CONFIG", resetValue) | ||||
|  | ||||
| 		// test | ||||
| 		correctWhitesourceDockerConfigEnvVar(&ScanOptions{DockerConfigJSON: dockerConfigFile, ScanImageRegistryURL: "https://test.registry", ContainerRegistryUser: "testuser", ContainerRegistryPassword: "testPassword"}, utilsMock) | ||||
| 		// assert | ||||
| 		absoluteDirPath, _ := utilsMock.Abs(filepath.Dir(dockerConfigFile)) | ||||
| 		absoluteFilePath, _ := utilsMock.Abs(dockerConfigFile) | ||||
| 		assert.Equal(t, absoluteDirPath, os.Getenv("DOCKER_CONFIG")) | ||||
| 		content, _ := utilsMock.FileRead(absoluteFilePath) | ||||
| 		assert.Contains(t, string(content), "https://test.registry") | ||||
| 	}) | ||||
| 	t.Run("without credentials", func(t *testing.T) { | ||||
| 		// init | ||||
| 		utilsMock := newWhitesourceUtilsMock() | ||||
| 		resetValue := os.Getenv("DOCKER_CONFIG") | ||||
| 		defer os.Setenv("DOCKER_CONFIG", resetValue) | ||||
| 		// test | ||||
| 		correctWhitesourceDockerConfigEnvVar(&ScanOptions{}) | ||||
| 		correctWhitesourceDockerConfigEnvVar(&ScanOptions{}, utilsMock) | ||||
| 		// assert | ||||
| 		assert.Equal(t, resetValue, os.Getenv("DOCKER_CONFIG")) | ||||
| 	}) | ||||
|   | ||||
| @@ -113,6 +113,28 @@ spec: | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         default: ./wss-unified-agent.config | ||||
|       - 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: 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: custom/repositoryUsername | ||||
|       - name: createProductFromPipeline | ||||
|         type: bool | ||||
|         description: "Whether to create the related WhiteSource product on the fly based on the supplied pipeline | ||||
|   | ||||
		Reference in New Issue
	
	Block a user