Skip to content

Commit

Permalink
Revert "feat(cnbBuild): validate docker credentials (#4840)" (#4872)
Browse files Browse the repository at this point in the history
Apparently this pr caused some regression.

This reverts commit df2e976.
  • Loading branch information
c0d1ngm0nk3y authored Mar 25, 2024
1 parent 2d2d357 commit 70dac23
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 154 deletions.
9 changes: 1 addition & 8 deletions cmd/cnbBuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,19 +529,12 @@ func runCnbBuild(config *cnbBuildOptions, telemetry *buildpacks.Telemetry, image
}
}

credentials := cnbutils.NewCredentials(utils)
cnbRegistryAuth, err := credentials.GenerateCredentials(config.DockerConfigJSON)
cnbRegistryAuth, err := cnbutils.GenerateCnbAuth(config.DockerConfigJSON, utils)
if err != nil {
log.SetErrorCategory(log.ErrorConfiguration)
return errors.Wrap(err, "failed to generate CNB_REGISTRY_AUTH")
}

found := credentials.Validate(targetImage.ContainerRegistry.Host)
if !found {
log.SetErrorCategory(log.ErrorConfiguration)
return errors.New(fmt.Sprintf("DockerConfigJSON does not contain credentials for target registry (%s)", targetImage.ContainerRegistry.Host))
}

if len(config.CustomTLSCertificateLinks) > 0 {
caCertificates := "/tmp/ca-certificates.crt"
_, err := utils.Copy("/etc/ssl/certs/ca-certificates.crt", caCertificates)
Expand Down
86 changes: 25 additions & 61 deletions cmd/cnbBuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@ func TestRunCnbBuild(t *testing.T) {
`

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile("project.toml", []byte(projectToml))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{})

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assertLifecycleCalls(t, runner, 2)
assert.Contains(t, runner.Calls[1].Params, fmt.Sprintf("%s/%s:%s", imageRegistry, config.ContainerImageName, config.ContainerImageTag))
assert.Contains(t, runner.Calls[1].Params, "-run-image")
Expand All @@ -160,7 +160,7 @@ func TestRunCnbBuild(t *testing.T) {
`

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile("project.toml", []byte(projectToml))
addBuilderFiles(&utils)

Expand All @@ -169,7 +169,7 @@ func TestRunCnbBuild(t *testing.T) {

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assertLifecycleCalls(t, runner, 2)
assert.Contains(t, runner.Calls[1].Params, fmt.Sprintf("%s/%s:%s", imageRegistry, "io-buildpacks-my-app", config.ContainerImageTag))
assert.Equal(t, config.ContainerRegistryURL, commonPipelineEnvironment.container.registryURL)
Expand All @@ -190,14 +190,14 @@ func TestRunCnbBuild(t *testing.T) {
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{})

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assertLifecycleCalls(t, runner, 2)
assert.Contains(t, runner.Calls[1].Params, fmt.Sprintf("%s/%s:%s", imageRegistry, config.ContainerImageName, config.ContainerImageTag))
assert.Equal(t, config.ContainerRegistryURL, commonPipelineEnvironment.container.registryURL)
Expand All @@ -215,14 +215,14 @@ func TestRunCnbBuild(t *testing.T) {
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{})

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assertLifecycleCalls(t, runner, 2)
assert.Contains(t, runner.Calls[1].Params, fmt.Sprintf("%s/%s:%s", config.ContainerRegistryURL, config.ContainerImageName, config.ContainerImageTag))
assert.Equal(t, fmt.Sprintf("https://%s", config.ContainerRegistryURL), commonPipelineEnvironment.container.registryURL)
Expand All @@ -245,14 +245,14 @@ func TestRunCnbBuild(t *testing.T) {
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{})

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Equal(t, creatorPath, runner.Calls[1].Exec)
assert.Contains(t, runner.Calls[1].Params, "/tmp/buildpacks")
assert.Contains(t, runner.Calls[1].Params, "/tmp/buildpacks/order.toml")
Expand Down Expand Up @@ -283,14 +283,14 @@ func TestRunCnbBuild(t *testing.T) {
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{})

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Equal(t, creatorPath, runner.Calls[1].Exec)
assert.Contains(t, runner.Calls[1].Params, "/tmp/buildpacks")
assert.Contains(t, runner.Calls[1].Params, "/tmp/buildpacks/order.toml")
Expand Down Expand Up @@ -319,14 +319,14 @@ func TestRunCnbBuild(t *testing.T) {
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{})

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Equal(t, creatorPath, runner.Calls[1].Exec)
assert.Contains(t, runner.Calls[1].Params, "/tmp/buildpacks")
assert.Contains(t, runner.Calls[1].Params, "/tmp/buildpacks/order.toml")
Expand Down Expand Up @@ -358,7 +358,7 @@ func TestRunCnbBuild(t *testing.T) {

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(caCertsFile, []byte("test\n"))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, client)
Expand All @@ -370,7 +370,7 @@ func TestRunCnbBuild(t *testing.T) {

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, fmt.Sprintf("SSL_CERT_FILE=%s", caCertsTmpFile))
assertLifecycleCalls(t, runner, 2)
assert.Contains(t, runner.Calls[1].Params, fmt.Sprintf("%s/%s:%s", config.ContainerRegistryURL, config.ContainerImageName, config.ContainerImageTag))
Expand All @@ -387,7 +387,7 @@ func TestRunCnbBuild(t *testing.T) {
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{})
Expand All @@ -412,7 +412,6 @@ func TestRunCnbBuild(t *testing.T) {
"OPTIONS_KEY": "OPTIONS_VALUE",
"OVERWRITE": "this should win",
},
DockerConfigJSON: "/path/to/config.json",
}

projectToml := `[project]
Expand All @@ -428,7 +427,6 @@ func TestRunCnbBuild(t *testing.T) {
`

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile("project.toml", []byte(projectToml))
addBuilderFiles(&utils)

Expand All @@ -455,7 +453,7 @@ func TestRunCnbBuild(t *testing.T) {
utils := newCnbBuildTestsUtils()
utils.FilesMock.CurrentDir = "/jenkins"
utils.FilesMock.AddDir("/jenkins")
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile("/workspace/pom.xml", []byte("test"))
addBuilderFiles(&utils)

Expand All @@ -480,7 +478,7 @@ func TestRunCnbBuild(t *testing.T) {
utils := newCnbBuildTestsUtils()
utils.FilesMock.CurrentDir = "/jenkins"
utils.FilesMock.AddDir("/jenkins")
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{})
Expand All @@ -502,30 +500,13 @@ func TestRunCnbBuild(t *testing.T) {
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":"dXNlcjpwYXNz"}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":"dXNlcjpwYXNz"}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{})
assert.EqualError(t, err, "failed to generate CNB_REGISTRY_AUTH: json: cannot unmarshal string into Go struct field ConfigFile.auths of type types.AuthConfig")
})

t.Run("error case: missing target registry in docker credentials", func(t *testing.T) {
t.Parallel()
config := cnbBuildOptions{
ContainerImageTag: "0.0.1",
ContainerRegistryURL: imageRegistry,
ContainerImageName: "my-image",
DockerConfigJSON: "/path/to/config.json",
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-other-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{})
assert.EqualError(t, err, "DockerConfigJSON does not contain credentials for target registry (some-registry)")
})

t.Run("error case: DockerConfigJSON file not there (config.json)", func(t *testing.T) {
t.Parallel()
config := cnbBuildOptions{
Expand Down Expand Up @@ -580,7 +561,7 @@ func TestRunCnbBuild(t *testing.T) {
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{})
Expand All @@ -602,26 +583,9 @@ func TestRunCnbBuild(t *testing.T) {
"runImage": "bar",
},
},
DockerConfigJSON: "/path/to/config.json",
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddDir("target")
utils.FilesMock.AddFile("target/project.toml", []byte(`[project]
id = "test"
name = "test"
version = "1.0.0"
[build]
include = []
exclude = ["*.tar"]
[[build.buildpacks]]
uri = "some-buildpack"`))
utils.FilesMock.AddFile("a_file", []byte(`{}`))
utils.FilesMock.AddFile("target/somelib.jar", []byte(`FFFFFF`))

addBuilderFiles(&utils)

telemetryData := &telemetry.CustomData{}
Expand All @@ -646,7 +610,7 @@ uri = "some-buildpack"`))
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddDir("target")
utils.FilesMock.AddFile("target/app.jar", []byte(`FFFFFF`))
utils.FilesMock.AddFile("target/app-src.jar", []byte(`FFFFFF`))
Expand All @@ -673,7 +637,7 @@ uri = "some-buildpack"`))
}

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddDir("target")
utils.FilesMock.AddFile("target/app.jar", []byte(`FFFFFF`))

Expand All @@ -684,7 +648,7 @@ uri = "some-buildpack"`))

require.NoError(t, err)
runner := utils.ExecMockRunner
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"some-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}")
assert.Contains(t, runner.Calls[1].Params, fmt.Sprintf("%s/%s:%s", imageRegistry, config.ContainerImageName, config.ContainerImageTag))
assert.Equal(t, config.ContainerRegistryURL, commonPipelineEnvironment.container.registryURL)
assert.Equal(t, "my-image:3.1.5", commonPipelineEnvironment.container.imageNameTag)
Expand All @@ -704,7 +668,7 @@ uri = "some-buildpack"`))
expectedImageCount := len(config.MultipleImages)

utils := newCnbBuildTestsUtils()
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"some-registry":{"auth":"dXNlcjpwYXNz"}}}`))
utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`))
addBuilderFiles(&utils)

telemetryData := &telemetry.CustomData{}
Expand Down
46 changes: 5 additions & 41 deletions pkg/cnbutils/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,30 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"strings"

"github.com/SAP/jenkins-library/pkg/log"
"github.com/docker/cli/cli/config/configfile"
)

type Credentials struct {
utils BuildUtils
dockerConfig *configfile.ConfigFile
}

func NewCredentials(utils BuildUtils) Credentials {
return Credentials{
utils: utils,
dockerConfig: nil,
}
}

func (c *Credentials) GenerateCredentials(config string) (string, error) {
func GenerateCnbAuth(config string, utils BuildUtils) (string, error) {
var err error
c.dockerConfig, err = c.parse(config)
if err != nil {
return "", err
}

return c.generate()
}

func (c *Credentials) Validate(target string) bool {
if c.dockerConfig == nil {
return false
}
_, ok := c.dockerConfig.AuthConfigs[target]
if !strings.HasPrefix(target, "localhost") && !ok {
return false
}
return true
}

func (c *Credentials) parse(config string) (*configfile.ConfigFile, error) {
dockerConfig := &configfile.ConfigFile{}

if config != "" {
log.Entry().Debugf("using docker config file %q", config)
dockerConfigJSON, err := c.utils.FileRead(config)
dockerConfigJSON, err := utils.FileRead(config)
if err != nil {
return &configfile.ConfigFile{}, err
return "", err
}

err = json.Unmarshal(dockerConfigJSON, dockerConfig)
if err != nil {
return &configfile.ConfigFile{}, err
return "", err
}
}
return dockerConfig, nil
}

func (c *Credentials) generate() (string, error) {
auth := map[string]string{}
for registry, value := range c.dockerConfig.AuthConfigs {
for registry, value := range dockerConfig.AuthConfigs {
if value.Auth == "" && value.Username == "" && value.Password == "" {
log.Entry().Warnf("docker config.json contains empty credentials for registry %q. Either 'auth' or 'username' and 'password' have to be provided.", registry)
continue
Expand Down
Loading

0 comments on commit 70dac23

Please sign in to comment.