Skip to content

Commit

Permalink
feat(cnbBuild): support setting registry username and password via pa…
Browse files Browse the repository at this point in the history
…rameters (#4426)

* feat(cnbBuild): support setting registry username and password via parameters

* fix gitops integration test assertion

Co-authored-by: Pavel Busko <[email protected]>

* Update integration/integration_gitops_test.go

---------

Co-authored-by: Ralf Pannemans <[email protected]>
  • Loading branch information
pbusko and c0d1ngm0nk3y authored Jun 30, 2023
1 parent a614923 commit d8dacda
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 26 deletions.
18 changes: 17 additions & 1 deletion cmd/cnbBuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,10 +385,26 @@ func callCnbBuild(config *cnbBuildOptions, telemetryData *telemetry.CustomData,
err = renameDockerConfig(config, utils)
if err != nil {
log.SetErrorCategory(log.ErrorConfiguration)
return errors.Wrapf(err, "failed to rename DockerConfigJSON file '%v'", config.DockerConfigJSON)
return errors.Wrapf(err, "failed to rename DockerConfigJSON file '%s'", config.DockerConfigJSON)
}
}

if config.ContainerRegistryUser != "" && config.ContainerRegistryPassword != "" {
log.Entry().Debug("enhancing docker config with the provided credentials")
if config.DockerConfigJSON == "" {
config.DockerConfigJSON = "/tmp/config.json"
}
log.Entry().Debugf("using docker config file %q", config.DockerConfigJSON)

_, err = docker.CreateDockerConfigJSON(config.ContainerRegistryURL, config.ContainerRegistryUser, config.ContainerRegistryPassword, "", config.DockerConfigJSON, utils)
if err != nil {
log.SetErrorCategory(log.ErrorBuild)
return errors.Wrapf(err, "failed to update DockerConfigJSON file %q", config.DockerConfigJSON)
}

log.Entry().Debugf("docker config %q has been updated", config.DockerConfigJSON)
}

mergedConfigs, err := processConfigs(*config, config.MultipleImages)
if err != nil {
return errors.Wrap(err, "failed to process config")
Expand Down
37 changes: 32 additions & 5 deletions cmd/cnbBuild_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions integration/docker_test_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,7 @@ func (d *IntegrationTestDockerExecRunner) assertFileContentEquals(t *testing.T,
t.Fatalf("unable to get tar file content: %s", err)
}

if !strings.Contains(str.String(), contentWant) {
assert.Equal(t, str.String(), contentWant, fmt.Sprintf("Unexpected content of file '%s'", fileWant))
}
assert.Equal(t, str.String(), contentWant, fmt.Sprintf("Unexpected content of file '%s'", fileWant))
}

func (d *IntegrationTestDockerExecRunner) terminate(t *testing.T) {
Expand Down
28 changes: 14 additions & 14 deletions integration/integration_cnb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ func TestCNBIntegrationNPMProject(t *testing.T) {
"PIPER_VAULTCREDENTIAL_DYNATRACE_API_KEY": "api-key-content",
},
})
defer container.terminate(t)

container2 := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{
Image: baseBuilder,
Expand All @@ -61,9 +60,8 @@ func TestCNBIntegrationNPMProject(t *testing.T) {
"PIPER_VAULTCREDENTIAL_DYNATRACE_API_KEY": "api-key-content",
},
})
defer container2.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--path", "TestCnbIntegration/project", "--customConfig", "TestCnbIntegration/config.yml", "--containerImageName", "node", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--defaultProcess", "greeter")
err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--path", "TestCnbIntegration/project", "--customConfig", "TestCnbIntegration/config.yml", "--containerImageName", "node", "--containerImageTag", "0.0.1", "--dockerConfigJSON", "TestCnbIntegration/config.json", "--containerRegistryUrl", registryURL, "--containerRegistryUser", "foo", "--containerRegistryPassword", "bar", "--defaultProcess", "greeter")
assert.NoError(t, err)
container.assertHasOutput(t, "running command: /cnb/lifecycle/creator")
container.assertHasOutput(t, "Selected Node Engine version (using BP_NODE_VERSION): 16")
Expand All @@ -72,16 +70,18 @@ func TestCNBIntegrationNPMProject(t *testing.T) {
container.assertHasOutput(t, "Setting default process type 'greeter'")
container.assertHasOutput(t, "*** Images (sha256:")
container.assertHasOutput(t, "SUCCESS")
container.assertFileContentEquals(t, "/project/TestCnbIntegration/config.json", "{\"auths\":{\"localhost:5000\":{\"auth\":\"Zm9vOmJhcg==\"},\"test.registry.io\":{}}}")
container.terminate(t)

err = container2.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--path", "TestCnbIntegration/project", "--customConfig", "TestCnbIntegration/config.yml", "--containerImageName", "node", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--projectDescriptor", "project-with-id.toml")
err = container2.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--path", "TestCnbIntegration/project", "--customConfig", "TestCnbIntegration/config.yml", "--containerImageName", "node", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--containerRegistryUser", "foo", "--containerRegistryPassword", "bar", "--projectDescriptor", "project-with-id.toml")
assert.NoError(t, err)
container2.assertHasOutput(t, "running command: /cnb/lifecycle/creator")
container2.assertHasOutput(t, "Selected Node Engine version (using BP_NODE_VERSION): 16")
container2.assertHasOutput(t, "Paketo NPM Start Buildpack")
container2.assertHasOutput(t, fmt.Sprintf("Saving %s/node:0.0.1", registryURL))
container2.assertHasOutput(t, "*** Images (sha256:")
container2.assertHasOutput(t, "SUCCESS")
container2.assertFileContentEquals(t, "/tmp/config.json", "{\"auths\":{\"localhost:5000\":{\"auth\":\"Zm9vOmJhcg==\"}}}")
container2.terminate(t)
}

Expand All @@ -97,7 +97,6 @@ func TestCNBIntegrationProjectDescriptor(t *testing.T) {
TestDir: []string{"testdata", "TestCnbIntegration", "project"},
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL)
assert.NoError(t, err)
Expand All @@ -114,6 +113,7 @@ func TestCNBIntegrationProjectDescriptor(t *testing.T) {
"*** Images (sha256:",
"SUCCESS",
)
container.terminate(t)
}

func TestCNBIntegrationZipPath(t *testing.T) {
Expand All @@ -128,7 +128,6 @@ func TestCNBIntegrationZipPath(t *testing.T) {
TestDir: []string{"testdata", "TestCnbIntegration", "zip"},
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--path", "go.zip", "--createBOM")
assert.NoError(t, err)
Expand All @@ -143,6 +142,7 @@ func TestCNBIntegrationZipPath(t *testing.T) {
"syft packages registry:localhost:5000/not-found:0.0.1 -o cyclonedx-xml --file bom-docker-0.xml -q",
)
container.assertHasFiles(t, "/project/bom-docker-0.xml")
container.terminate(t)
}

func TestCNBIntegrationNonZipPath(t *testing.T) {
Expand All @@ -157,12 +157,12 @@ func TestCNBIntegrationNonZipPath(t *testing.T) {
TestDir: []string{"testdata", "TestMtaIntegration", "npm"},
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--path", "mta.yaml")
assert.Error(t, err)

container.assertHasOutput(t, "Copying '/project/mta.yaml' into '/workspace' failed: application path must be a directory or zip")
container.terminate(t)
}

func TestCNBIntegrationNPMCustomBuildpacksFullProject(t *testing.T) {
Expand All @@ -177,7 +177,6 @@ func TestCNBIntegrationNPMCustomBuildpacksFullProject(t *testing.T) {
TestDir: []string{"testdata", "TestMtaIntegration", "npm"},
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--buildpacks", "gcr.io/paketo-buildpacks/nodejs:0.19.0", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL)
assert.NoError(t, err)
Expand All @@ -191,6 +190,7 @@ func TestCNBIntegrationNPMCustomBuildpacksFullProject(t *testing.T) {
"*** Images (sha256:",
"SUCCESS",
)
container.terminate(t)
}

func TestCNBIntegrationNPMCustomBuildpacksBuildpacklessProject(t *testing.T) {
Expand All @@ -205,7 +205,6 @@ func TestCNBIntegrationNPMCustomBuildpacksBuildpacklessProject(t *testing.T) {
TestDir: []string{"testdata", "TestMtaIntegration", "npm"},
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--buildpacks", "gcr.io/paketo-buildpacks/nodejs:0.19.0", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL)
assert.NoError(t, err)
Expand All @@ -218,6 +217,7 @@ func TestCNBIntegrationNPMCustomBuildpacksBuildpacklessProject(t *testing.T) {
"*** Images (sha256:",
"SUCCESS",
)
container.terminate(t)
}

func TestCNBIntegrationWrongBuilderProject(t *testing.T) {
Expand All @@ -226,12 +226,12 @@ func TestCNBIntegrationWrongBuilderProject(t *testing.T) {
Image: "nginx:latest",
TestDir: []string{"testdata", "TestMtaIntegration", "npm"},
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", "test")
assert.Error(t, err)

container.assertHasOutput(t, "the provided dockerImage is not a valid builder")
container.terminate(t)
}

func TestCNBIntegrationBindings(t *testing.T) {
Expand All @@ -249,7 +249,6 @@ func TestCNBIntegrationBindings(t *testing.T) {
"PIPER_VAULTCREDENTIAL_DYNATRACE_API_KEY": "api-key-content",
},
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--customConfig", "TestCnbIntegration/config.yml", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--path", "TestMtaIntegration/maven")
assert.Error(t, err)
Expand All @@ -261,6 +260,7 @@ func TestCNBIntegrationBindings(t *testing.T) {
)
container.assertFileContentEquals(t, "/tmp/platform/bindings/maven-settings/settings.xml", "invalid xml")
container.assertFileContentEquals(t, "/tmp/platform/bindings/dynatrace/api-key", "api-key-content")
container.terminate(t)
}

func TestCNBIntegrationMultiImage(t *testing.T) {
Expand All @@ -275,7 +275,6 @@ func TestCNBIntegrationMultiImage(t *testing.T) {
TestDir: []string{"testdata", "TestCnbIntegration"},
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--customConfig", "config_multi_image.yml", "--createBOM")
assert.NoError(t, err)
Expand All @@ -295,6 +294,7 @@ func TestCNBIntegrationMultiImage(t *testing.T) {
container.assertHasFiles(t, "/project/bom-docker-0.xml")
container.assertHasFiles(t, "/project/bom-docker-1.xml")
container.assertHasFiles(t, "/project/bom-docker-2.xml")
container.terminate(t)
}

func TestCNBIntegrationPreserveFiles(t *testing.T) {
Expand All @@ -309,12 +309,12 @@ func TestCNBIntegrationPreserveFiles(t *testing.T) {
TestDir: []string{"testdata", "TestCnbIntegration"},
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--customConfig", "config_preserve_files.yml")
assert.NoError(t, err)

container.assertHasFiles(t, "/project/project/node_modules/base/README.md", "/project/project/package-lock.json")
container.terminate(t)
}

func TestCNBIntegrationPreserveFilesIgnored(t *testing.T) {
Expand All @@ -329,9 +329,9 @@ func TestCNBIntegrationPreserveFilesIgnored(t *testing.T) {
TestDir: []string{"testdata", "TestCnbIntegration"},
Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()),
})
defer container.terminate(t)

err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--customConfig", "config_preserve_files.yml", "--path", "zip/go.zip", "--containerImageName", "go-zip")
assert.NoError(t, err)
container.assertHasOutput(t, "skipping preserving files because the source")
container.terminate(t)
}
3 changes: 2 additions & 1 deletion integration/integration_gitops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ func TestGitOpsIntegrationUpdateDeployment(t *testing.T) {
newName: image
newTag: "456"
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization`)
kind: Kustomization
`)
}
5 changes: 5 additions & 0 deletions integration/testdata/TestCnbIntegration/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"auths": {
"test.registry.io": {}
}
}
28 changes: 26 additions & 2 deletions resources/metadata/cnbBuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,32 @@ spec:
resourceRef:
- name: commonPipelineEnvironment
param: container/registryUrl
- name: containerRegistryUser
aliases:
- name: dockerRegistryUser
type: string
description: Username of the container registry where the image should be pushed to - which will updated in a docker config json file. If a docker config json file is provided via parameter `dockerConfigJSON`, then the existing file will be enhanced
scope:
- GENERAL
- PARAMETERS
- STAGES
- STEPS
resourceRef:
- name: commonPipelineEnvironment
param: container/repositoryUsername
- name: containerRegistryPassword
aliases:
- name: dockerRegistryPassword
type: string
description: Password of the container registry where the image should be pushed to - which will updated in a docker config json file. If a docker config json file is provided via parameter `dockerConfigJSON`, then the existing file will be enhanced
scope:
- GENERAL
- PARAMETERS
- STAGES
- STEPS
resourceRef:
- name: commonPipelineEnvironment
param: container/repositoryPassword
- name: buildpacks
type: "[]string"
description: List of custom buildpacks to use in the form of `$HOSTNAME/$REPO[:$TAG]`.
Expand Down Expand Up @@ -150,8 +176,6 @@ spec:
- PARAMETERS
secret: true
resourceRef:
- name: commonPipelineEnvironment
param: custom/dockerConfigJSON
- name: dockerConfigJsonCredentialsId
type: secret
- type: vaultSecretFile
Expand Down

0 comments on commit d8dacda

Please sign in to comment.