1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-11-06 09:09:19 +02:00

fix(whitesourceExecuteScan): docker image download if dockerConfigJSON is set in vault (#3591)

Co-authored-by: ffeldmann <f.feldmann@sap.com>
This commit is contained in:
Christian Volk
2022-02-28 13:57:23 +01:00
committed by GitHub
parent 246d37a2fb
commit 421168a169
7 changed files with 232 additions and 117 deletions

View File

@@ -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
}

View File

@@ -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"),
},
},
},
},

View File

@@ -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"))
})
}

View File

@@ -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")
}
}

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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