diff --git a/cmd/containerSaveImage.go b/cmd/containerSaveImage.go index ed4029632..ebb178008 100644 --- a/cmd/containerSaveImage.go +++ b/cmd/containerSaveImage.go @@ -1,12 +1,14 @@ package cmd import ( + "fmt" "os" "path/filepath" "strings" piperDocker "github.com/SAP/jenkins-library/pkg/docker" "github.com/SAP/jenkins-library/pkg/log" + "github.com/SAP/jenkins-library/pkg/piperutils" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/pkg/errors" @@ -19,13 +21,17 @@ func containerSaveImage(config containerSaveImageOptions, telemetryData *telemet dClient := &piperDocker.Client{} dClient.SetOptions(dClientOptions) - _, err := runContainerSaveImage(&config, telemetryData, cachePath, "", dClient) + _, err := runContainerSaveImage(&config, telemetryData, cachePath, "", dClient, piperutils.Files{}) if err != nil { log.Entry().WithError(err).Fatal("step execution failed") } } -func runContainerSaveImage(config *containerSaveImageOptions, telemetryData *telemetry.CustomData, cachePath, rootPath string, dClient piperDocker.Download) (string, error) { +func runContainerSaveImage(config *containerSaveImageOptions, telemetryData *telemetry.CustomData, cachePath, rootPath string, dClient piperDocker.Download, fileUtils piperutils.FileUtils) (string, error) { + if err := correctContainerDockerConfigEnvVar(config, fileUtils); err != nil { + return "", err + } + err := os.RemoveAll(cachePath) if err != nil { return "", errors.Wrap(err, "failed to prepare cache") @@ -76,3 +82,35 @@ func runContainerSaveImage(config *containerSaveImageOptions, telemetryData *tel func filenameFromContainer(rootPath, containerImage string) string { return filepath.Join(rootPath, strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(containerImage, "/", "_"), ":", "_"), ".", "_")+".tar") } + +func correctContainerDockerConfigEnvVar(config *containerSaveImageOptions, utils piperutils.FileUtils) error { + dockerConfigDir, err := utils.TempDir("", "docker") + + if err != nil { + return errors.Wrap(err, "unable to create docker config dir") + } + + dockerConfigFile := fmt.Sprintf("%s/%s", dockerConfigDir, "config.json") + + if len(config.DockerConfigJSON) > 0 { + log.Entry().Infof("Docker credentials configuration: %v", config.DockerConfigJSON) + + if exists, _ := utils.FileExists(config.DockerConfigJSON); exists { + if _, err = utils.Copy(config.DockerConfigJSON, dockerConfigFile); err != nil { + return errors.Wrap(err, "unable to copy docker config") + } + } + } else { + log.Entry().Info("Docker credentials configuration: NONE") + } + + if len(config.ContainerRegistryURL) > 0 && len(config.ContainerRegistryUser) > 0 && len(config.ContainerRegistryPassword) > 0 { + if _, err = piperDocker.CreateDockerConfigJSON(config.ContainerRegistryURL, config.ContainerRegistryUser, config.ContainerRegistryPassword, dockerConfigFile, dockerConfigFile, utils); err != nil { + log.Entry().Warningf("failed to update Docker config.json: %v", err) + } + } + + os.Setenv("DOCKER_CONFIG", dockerConfigDir) + + return nil +} diff --git a/cmd/containerSaveImage_generated.go b/cmd/containerSaveImage_generated.go index af788bd93..952afc4e9 100644 --- a/cmd/containerSaveImage_generated.go +++ b/cmd/containerSaveImage_generated.go @@ -16,10 +16,13 @@ import ( ) type containerSaveImageOptions struct { - ContainerRegistryURL string `json:"containerRegistryUrl,omitempty"` - ContainerImage string `json:"containerImage,omitempty"` - FilePath string `json:"filePath,omitempty"` - IncludeLayers bool `json:"includeLayers,omitempty"` + ContainerRegistryURL string `json:"containerRegistryUrl,omitempty"` + ContainerImage string `json:"containerImage,omitempty"` + ContainerRegistryPassword string `json:"containerRegistryPassword,omitempty"` + ContainerRegistryUser string `json:"containerRegistryUser,omitempty"` + FilePath string `json:"filePath,omitempty"` + IncludeLayers bool `json:"includeLayers,omitempty"` + DockerConfigJSON string `json:"dockerConfigJSON,omitempty"` } // ContainerSaveImageCommand Saves a container image as a tar file @@ -55,6 +58,9 @@ It can be used no matter if a Docker daemon is available or not. It will also wo log.SetErrorCategory(log.ErrorConfiguration) return err } + log.RegisterSecret(stepConfig.ContainerRegistryPassword) + log.RegisterSecret(stepConfig.ContainerRegistryUser) + log.RegisterSecret(stepConfig.DockerConfigJSON) if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 { sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID) @@ -115,8 +121,11 @@ It can be used no matter if a Docker daemon is available or not. It will also wo func addContainerSaveImageFlags(cmd *cobra.Command, stepConfig *containerSaveImageOptions) { cmd.Flags().StringVar(&stepConfig.ContainerRegistryURL, "containerRegistryUrl", os.Getenv("PIPER_containerRegistryUrl"), "The reference to the container registry where the image is located.") cmd.Flags().StringVar(&stepConfig.ContainerImage, "containerImage", os.Getenv("PIPER_containerImage"), "Container image to be saved.") + 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.FilePath, "filePath", os.Getenv("PIPER_filePath"), "The path to the file to which the image should be saved. Defaults to `containerImage.tar`") cmd.Flags().BoolVar(&stepConfig.IncludeLayers, "includeLayers", false, "Flag if the docker layers should be included") + 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.MarkFlagRequired("containerRegistryUrl") cmd.MarkFlagRequired("containerImage") @@ -132,6 +141,9 @@ func containerSaveImageMetadata() config.StepData { }, Spec: config.StepSpec{ Inputs: config.StepInputs{ + Secrets: []config.StepSecrets{ + {Name: "dockerConfigJsonCredentialsId", Description: "Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)). You can find more details about the Docker credentials in the [Docker documentation](https://docs.docker.com/engine/reference/commandline/login/).", Type: "jenkins", Aliases: []config.Alias{{Name: "dockerCredentialsId", Deprecated: true}}}, + }, Parameters: []config.StepParameters{ { Name: "containerRegistryUrl", @@ -161,6 +173,34 @@ func containerSaveImageMetadata() config.StepData { Aliases: []config.Alias{{Name: "dockerImage"}, {Name: "scanImage"}}, Default: os.Getenv("PIPER_containerImage"), }, + { + 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: "filePath", ResourceRef: []config.ResourceReference{}, @@ -179,6 +219,31 @@ func containerSaveImageMetadata() config.StepData { Aliases: []config.Alias{}, Default: false, }, + { + Name: "dockerConfigJSON", + ResourceRef: []config.ResourceReference{ + { + Name: "commonPipelineEnvironment", + Param: "custom/dockerConfigJSON", + }, + + { + Name: "dockerConfigJsonCredentialsId", + Type: "secret", + }, + + { + Name: "dockerConfigFileVaultSecretName", + Type: "vaultSecretFile", + Default: "docker-config", + }, + }, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: os.Getenv("PIPER_dockerConfigJSON"), + }, }, }, }, diff --git a/cmd/containerSaveImage_test.go b/cmd/containerSaveImage_test.go index b370ee8c7..d09feddbf 100644 --- a/cmd/containerSaveImage_test.go +++ b/cmd/containerSaveImage_test.go @@ -9,6 +9,7 @@ import ( "testing" pkgutil "github.com/GoogleContainerTools/container-diff/pkg/util" + "github.com/SAP/jenkins-library/pkg/mock" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/stretchr/testify/assert" ) @@ -64,8 +65,9 @@ func TestRunContainerSaveImage(t *testing.T) { config.FilePath = "testfile" dClient := containerMock{} + files := mock.FilesMock{} - filePath, err := runContainerSaveImage(&config, &telemetryData, cacheFolder, tmpFolder, &dClient) + filePath, err := runContainerSaveImage(&config, &telemetryData, cacheFolder, tmpFolder, &dClient, &files) assert.NoError(t, err) assert.Equal(t, cacheFolder, dClient.filePath) @@ -81,7 +83,8 @@ func TestRunContainerSaveImage(t *testing.T) { t.Run("failure - cache creation", func(t *testing.T) { config := containerSaveImageOptions{} dClient := containerMock{} - _, err := runContainerSaveImage(&config, &telemetryData, "", "", &dClient) + files := mock.FilesMock{} + _, err := runContainerSaveImage(&config, &telemetryData, "", "", &dClient, &files) assert.Contains(t, fmt.Sprint(err), "failed to create cache: mkdir :") }) @@ -94,7 +97,8 @@ func TestRunContainerSaveImage(t *testing.T) { defer os.RemoveAll(tmpFolder) dClient := containerMock{imageSourceErr: "image source error"} - _, err = runContainerSaveImage(&config, &telemetryData, filepath.Join(tmpFolder, "cache"), tmpFolder, &dClient) + files := mock.FilesMock{} + _, err = runContainerSaveImage(&config, &telemetryData, filepath.Join(tmpFolder, "cache"), tmpFolder, &dClient, &files) assert.EqualError(t, err, "failed to get docker image source: image source error") }) @@ -107,7 +111,8 @@ func TestRunContainerSaveImage(t *testing.T) { defer os.RemoveAll(tmpFolder) dClient := containerMock{downloadImageErr: "download error"} - _, err = runContainerSaveImage(&config, &telemetryData, filepath.Join(tmpFolder, "cache"), tmpFolder, &dClient) + files := mock.FilesMock{} + _, err = runContainerSaveImage(&config, &telemetryData, filepath.Join(tmpFolder, "cache"), tmpFolder, &dClient, &files) assert.EqualError(t, err, "failed to download docker image: download error") }) @@ -120,7 +125,8 @@ func TestRunContainerSaveImage(t *testing.T) { defer os.RemoveAll(tmpFolder) dClient := containerMock{tarImageErr: "tar error"} - _, err = runContainerSaveImage(&config, &telemetryData, filepath.Join(tmpFolder, "cache"), tmpFolder, &dClient) + files := mock.FilesMock{} + _, err = runContainerSaveImage(&config, &telemetryData, filepath.Join(tmpFolder, "cache"), tmpFolder, &dClient, &files) assert.EqualError(t, err, "failed to tar container image: tar error") }) } @@ -143,3 +149,54 @@ func TestFilenameFromContainer(t *testing.T) { } } + +func TestCorrectContainerDockerConfigEnvVar(t *testing.T) { + t.Run("with credentials", func(t *testing.T) { + // init + utilsMock := mock.FilesMock{} + utilsMock.CurrentDir = "/tmp/test" + + dockerConfigFile := "myConfig/docker.json" + utilsMock.AddFile(dockerConfigFile, []byte("{}")) + + resetValue := os.Getenv("DOCKER_CONFIG") + os.Setenv("DOCKER_CONFIG", "") + defer os.Setenv("DOCKER_CONFIG", resetValue) + + // test + correctContainerDockerConfigEnvVar(&containerSaveImageOptions{DockerConfigJSON: dockerConfigFile}, &utilsMock) + // assert + assert.NotNil(t, os.Getenv("DOCKER_CONFIG")) + }) + t.Run("with added credentials", func(t *testing.T) { + // init + utilsMock := mock.FilesMock{} + utilsMock.CurrentDir = "/tmp/test" + + dockerConfigFile := "myConfig/docker.json" + utilsMock.AddFile(dockerConfigFile, []byte("{}")) + + resetValue := os.Getenv("DOCKER_CONFIG") + os.Setenv("DOCKER_CONFIG", "") + defer os.Setenv("DOCKER_CONFIG", resetValue) + + // test + correctContainerDockerConfigEnvVar(&containerSaveImageOptions{DockerConfigJSON: dockerConfigFile, ContainerRegistryURL: "https://test.registry", ContainerRegistryUser: "testuser", ContainerRegistryPassword: "testPassword"}, &utilsMock) + // assert + assert.NotNil(t, os.Getenv("DOCKER_CONFIG")) + absoluteFilePath, _ := utilsMock.Abs(fmt.Sprintf("%s/%s", os.Getenv("DOCKER_CONFIG"), "config.json")) + content, _ := utilsMock.FileRead(absoluteFilePath) + assert.Contains(t, string(content), "https://test.registry") + }) + t.Run("without credentials", func(t *testing.T) { + // init + utilsMock := mock.FilesMock{} + resetValue := os.Getenv("DOCKER_CONFIG") + os.Setenv("DOCKER_CONFIG", "") + defer os.Setenv("DOCKER_CONFIG", resetValue) + // test + correctContainerDockerConfigEnvVar(&containerSaveImageOptions{}, &utilsMock) + // assert + assert.NotNil(t, os.Getenv("DOCKER_CONFIG")) + }) +} diff --git a/cmd/malwareExecuteScan.go b/cmd/malwareExecuteScan.go index 2b6d87e16..ad0a9df87 100644 --- a/cmd/malwareExecuteScan.go +++ b/cmd/malwareExecuteScan.go @@ -13,7 +13,6 @@ import ( "github.com/pkg/errors" "io" "os" - "path/filepath" "strings" "time" ) @@ -145,18 +144,19 @@ func selectAndPrepareFileForMalwareScan(config *malwareExecuteScanOptions, utils // automatically detect the file to be scanned depending on the buildtool if len(config.ScanImage) > 0 { - correctMalwareDockerConfigEnvVar(config, utils) - saveImageOptions := containerSaveImageOptions{ - ContainerImage: config.ScanImage, - ContainerRegistryURL: config.ScanImageRegistryURL, - IncludeLayers: config.ScanImageIncludeLayers, - FilePath: config.ScanImage, + ContainerImage: config.ScanImage, + ContainerRegistryURL: config.ScanImageRegistryURL, + ContainerRegistryUser: config.ContainerRegistryUser, + ContainerRegistryPassword: config.ContainerRegistryPassword, + DockerConfigJSON: config.DockerConfigJSON, + IncludeLayers: config.ScanImageIncludeLayers, + FilePath: config.ScanImage, } dClientOptions := piperDocker.ClientOptions{ImageName: saveImageOptions.ContainerImage, RegistryURL: saveImageOptions.ContainerRegistryURL, LocalPath: "", IncludeLayers: saveImageOptions.IncludeLayers} dClient := utils.newDockerClient(dClientOptions) - tarFile, err := runContainerSaveImage(&saveImageOptions, &telemetry.CustomData{}, "./cache", "", dClient) + tarFile, err := runContainerSaveImage(&saveImageOptions, &telemetry.CustomData{}, "./cache", "", dClient, utils) if err != nil { if strings.Contains(fmt.Sprint(err), "no image found") { @@ -215,23 +215,3 @@ func createMalwareScanReport(config *malwareExecuteScanOptions, scanResult *malw return utils.FileWrite(config.ReportFileName, scanResultJSON, 0666) } - -func correctMalwareDockerConfigEnvVar(config *malwareExecuteScanOptions, utils malwareScanUtils) { - path := config.DockerConfigJSON - if len(path) > 0 { - log.Entry().Infof("Docker credentials configuration: %v", 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) - } else { - log.Entry().Info("Docker credentials configuration: NONE") - } -} diff --git a/cmd/whitesourceExecuteScan.go b/cmd/whitesourceExecuteScan.go index 94f63d832..43f287b92 100644 --- a/cmd/whitesourceExecuteScan.go +++ b/cmd/whitesourceExecuteScan.go @@ -160,21 +160,22 @@ 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, utils) - // Download Docker image for container scan // ToDo: move it to improve testability if config.BuildTool == "docker" { saveImageOptions := containerSaveImageOptions{ - ContainerImage: config.ScanImage, - ContainerRegistryURL: config.ScanImageRegistryURL, - IncludeLayers: config.ScanImageIncludeLayers, - FilePath: config.ProjectName, + ContainerImage: config.ScanImage, + ContainerRegistryURL: config.ScanImageRegistryURL, + ContainerRegistryUser: config.ContainerRegistryUser, + ContainerRegistryPassword: config.ContainerRegistryPassword, + DockerConfigJSON: config.DockerConfigJSON, + IncludeLayers: config.ScanImageIncludeLayers, + FilePath: config.ProjectName, } dClientOptions := piperDocker.ClientOptions{ImageName: saveImageOptions.ContainerImage, RegistryURL: saveImageOptions.ContainerRegistryURL, LocalPath: "", IncludeLayers: saveImageOptions.IncludeLayers} dClient := &piperDocker.Client{} dClient.SetOptions(dClientOptions) - if _, err := runContainerSaveImage(&saveImageOptions, &telemetry.CustomData{}, "./cache", "", dClient); err != nil { + if _, err := runContainerSaveImage(&saveImageOptions, &telemetry.CustomData{}, "./cache", "", dClient, utils); err != nil { if strings.Contains(fmt.Sprint(err), "no image found") { log.SetErrorCategory(log.ErrorConfiguration) } @@ -212,26 +213,6 @@ func runWhitesourceScan(config *ScanOptions, scan *ws.Scan, utils whitesourceUti return nil } -func correctWhitesourceDockerConfigEnvVar(config *ScanOptions, utils whitesourceUtils) { - path := config.DockerConfigJSON - if len(path) > 0 { - log.Entry().Infof("Docker credentials configuration: %v", 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) - } else { - log.Entry().Info("Docker credentials configuration: NONE") - } -} - func checkAndReportScanResults(config *ScanOptions, scan *ws.Scan, utils whitesourceUtils, sys whitesource, influx *whitesourceExecuteScanInflux) ([]piperutils.Path, error) { reportPaths := []piperutils.Path{} if !config.Reporting && !config.SecurityVulnerabilities { diff --git a/cmd/whitesourceExecuteScan_test.go b/cmd/whitesourceExecuteScan_test.go index facc3b0fb..b103d491b 100644 --- a/cmd/whitesourceExecuteScan_test.go +++ b/cmd/whitesourceExecuteScan_test.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "os" "path/filepath" "testing" "time" @@ -130,56 +129,6 @@ func TestRunWhitesourceExecuteScan(t *testing.T) { }) } -func TestCorrectWhitesourceDockerConfigEnvVar(t *testing.T) { - t.Run("with 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}, utilsMock) - // assert - 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{}, utilsMock) - // assert - assert.Equal(t, resetValue, os.Getenv("DOCKER_CONFIG")) - }) -} - func TestCheckAndReportScanResults(t *testing.T) { t.Parallel() t.Run("no reports requested", func(t *testing.T) { diff --git a/resources/metadata/containerSaveImage.yaml b/resources/metadata/containerSaveImage.yaml index e22571953..5472290ed 100644 --- a/resources/metadata/containerSaveImage.yaml +++ b/resources/metadata/containerSaveImage.yaml @@ -7,6 +7,13 @@ metadata: It can be used no matter if a Docker daemon is available or not. It will also work inside a Kubernetes cluster without access to a daemon. spec: inputs: + secrets: + - name: dockerConfigJsonCredentialsId + description: Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)). You can find more details about the Docker credentials in the [Docker documentation](https://docs.docker.com/engine/reference/commandline/login/). + type: jenkins + aliases: + - name: dockerCredentialsId + deprecated: true params: - name: containerRegistryUrl aliases: @@ -37,6 +44,28 @@ 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: 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: filePath type: string description: The path to the file to which the image should be saved. Defaults to `containerImage.tar` @@ -51,3 +80,19 @@ spec: - PARAMETERS - STAGES - STEPS + - 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/). + scope: + - PARAMETERS + - STAGES + - STEPS + secret: true + resourceRef: + - name: commonPipelineEnvironment + param: custom/dockerConfigJSON + - name: dockerConfigJsonCredentialsId + type: secret + - type: vaultSecretFile + name: dockerConfigFileVaultSecretName + default: docker-config