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(cnbBuild): warn users when dockerConfigJSON is missing necessary credentials (#5007)
* feat(cnbBuild): warn users when dockerConfigJSON is missing necessary credentials * Update cmd/cnbBuild.go Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com> * Update pkg/cnbutils/auth.go Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com> * fix linting --------- Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com>
This commit is contained in:
		| @@ -2,10 +2,11 @@ package cmd | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/ans" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func ansSendEvent(config ansSendEventOptions, telemetryData *telemetry.CustomData) { | ||||
|   | ||||
| @@ -148,7 +148,7 @@ func validateAppName(appName string) error { | ||||
| 	} | ||||
| 	message = append(message, fmt.Sprintf("Please change the name to fit this requirement(s). For more details please visit %s.", docuLink)) | ||||
| 	if fail { | ||||
| 		return fmt.Errorf(strings.Join(message, " ")) | ||||
| 		return errors.New(strings.Join(message, " ")) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -168,18 +168,17 @@ func cleanDir(dir string, utils cnbutils.BuildUtils) error { | ||||
| } | ||||
|  | ||||
| func extractZip(source, target string) error { | ||||
| 	if isZip(source) { | ||||
| 		log.Entry().Infof("Extracting archive '%s' to '%s'", source, target) | ||||
| 		_, err := piperutils.Unzip(source, target) | ||||
| 		if err != nil { | ||||
| 			log.SetErrorCategory(log.ErrorBuild) | ||||
| 			return errors.Wrapf(err, "Extracting archive '%s' to '%s' failed", source, target) | ||||
| 		} | ||||
| 	} else { | ||||
| 	if !isZip(source) { | ||||
| 		log.SetErrorCategory(log.ErrorBuild) | ||||
| 		return errors.New("application path must be a directory or zip") | ||||
| 	} | ||||
|  | ||||
| 	log.Entry().Infof("Extracting archive '%s' to '%s'", source, target) | ||||
| 	_, err := piperutils.Unzip(source, target) | ||||
| 	if err != nil { | ||||
| 		log.SetErrorCategory(log.ErrorBuild) | ||||
| 		return errors.Wrapf(err, "Extracting archive '%s' to '%s' failed", source, target) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -537,12 +536,6 @@ func runCnbBuild(config *cnbBuildOptions, telemetry *buildpacks.Telemetry, image | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	cnbRegistryAuth, err := cnbutils.GenerateCnbAuth(config.DockerConfigJSON, utils) | ||||
| 	if err != nil { | ||||
| 		log.SetErrorCategory(log.ErrorConfiguration) | ||||
| 		return errors.Wrap(err, "failed to generate CNB_REGISTRY_AUTH") | ||||
| 	} | ||||
|  | ||||
| 	if len(config.CustomTLSCertificateLinks) > 0 { | ||||
| 		caCertificates := "/tmp/ca-certificates.crt" | ||||
| 		_, err := utils.Copy("/etc/ssl/certs/ca-certificates.crt", caCertificates) | ||||
| @@ -558,7 +551,17 @@ func runCnbBuild(config *cnbBuildOptions, telemetry *buildpacks.Telemetry, image | ||||
| 		log.Entry().Info("skipping certificates update") | ||||
| 	} | ||||
|  | ||||
| 	utils.AppendEnv([]string{fmt.Sprintf("CNB_REGISTRY_AUTH=%s", cnbRegistryAuth)}) | ||||
| 	dockerKeychain, err := cnbutils.ParseDockerConfig(config.DockerConfigJSON, utils) | ||||
| 	if err != nil { | ||||
| 		log.SetErrorCategory(log.ErrorConfiguration) | ||||
| 		return errors.Wrap(err, "failed to parse dockerConfigJSON") | ||||
| 	} | ||||
| 	cnbAuthString, err := dockerKeychain.ToCNBString() | ||||
| 	if err != nil { | ||||
| 		log.SetErrorCategory(log.ErrorConfiguration) | ||||
| 		return errors.Wrap(err, "failed to generate CNB_REGISTRY_AUTH") | ||||
| 	} | ||||
| 	utils.AppendEnv([]string{fmt.Sprintf("CNB_REGISTRY_AUTH=%s", cnbAuthString)}) | ||||
| 	utils.AppendEnv([]string{fmt.Sprintf("CNB_PLATFORM_API=%s", platformAPIVersion)}) | ||||
|  | ||||
| 	creatorArgs := []string{ | ||||
| @@ -574,6 +577,10 @@ func runCnbBuild(config *cnbBuildOptions, telemetry *buildpacks.Telemetry, image | ||||
| 	} | ||||
|  | ||||
| 	if config.RunImage != "" { | ||||
| 		if !dockerKeychain.AuthExistsForImage(config.RunImage) { | ||||
| 			log.Entry().Warnf("provided dockerConfigJSON does not contain credentials for the run-image %q, anonymous auth will be used", config.RunImage) | ||||
| 		} | ||||
|  | ||||
| 		creatorArgs = append(creatorArgs, "-run-image", config.RunImage) | ||||
| 	} | ||||
|  | ||||
| @@ -582,6 +589,9 @@ func runCnbBuild(config *cnbBuildOptions, telemetry *buildpacks.Telemetry, image | ||||
| 	} | ||||
|  | ||||
| 	containerImage := path.Join(targetImage.ContainerRegistry.Host, targetImage.ContainerImageName) | ||||
| 	if !dockerKeychain.AuthExistsForImage(containerImage) { | ||||
| 		log.Entry().Warnf("provided dockerConfigJSON does not contain credentials for the target image %q, anonymous auth will be used", containerImage) | ||||
| 	} | ||||
| 	for _, tag := range config.AdditionalTags { | ||||
| 		target := fmt.Sprintf("%s:%s", containerImage, tag) | ||||
| 		if !piperutils.ContainsString(creatorArgs, target) { | ||||
|   | ||||
| @@ -504,7 +504,7 @@ func TestRunCnbBuild(t *testing.T) { | ||||
| 		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") | ||||
| 		assert.EqualError(t, err, "failed to parse dockerConfigJSON: json: cannot unmarshal string into Go struct field ConfigFile.auths of type types.AuthConfig") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("error case: DockerConfigJSON file not there (config.json)", func(t *testing.T) { | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
| 	"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" | ||||
| ) | ||||
|  | ||||
| type contrastExecuteScanUtils interface { | ||||
| @@ -107,7 +108,7 @@ func runContrastExecuteScan(config *contrastExecuteScanOptions, telemetryData *t | ||||
| 				if unaudited > config.VulnerabilityThresholdTotal { | ||||
| 					msg := fmt.Sprintf("Your application %v in organization %v is not compliant. Total unaudited issues are %v which is greater than the VulnerabilityThresholdTotal count %v", | ||||
| 						config.ApplicationID, config.OrganizationID, unaudited, config.VulnerabilityThresholdTotal) | ||||
| 					return reports, fmt.Errorf(msg) | ||||
| 					return reports, errors.New(msg) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -845,7 +845,7 @@ func postScanChecksAndReporting(ctx context.Context, config detectExecuteScanOpt | ||||
| 	} | ||||
|  | ||||
| 	if len(errorsOccured) > 0 { | ||||
| 		return fmt.Errorf(strings.Join(errorsOccured, ": ")) | ||||
| 		return errors.New(strings.Join(errorsOccured, ": ")) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|   | ||||
| @@ -3,10 +3,11 @@ package cmd | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/evanphx/json-patch" | ||||
| 	jsonpatch "github.com/evanphx/json-patch" | ||||
| ) | ||||
|  | ||||
| func jsonApplyPatch(config jsonApplyPatchOptions, telemetryData *telemetry.CustomData) { | ||||
|   | ||||
| @@ -3,6 +3,11 @@ package cmd | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	piperDocker "github.com/SAP/jenkins-library/pkg/docker" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| @@ -11,10 +16,6 @@ import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/SAP/jenkins-library/pkg/toolrecord" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type malwareScanUtils interface { | ||||
|   | ||||
| @@ -1,12 +1,13 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| ) | ||||
|   | ||||
| @@ -2,13 +2,14 @@ package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"path/filepath" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"unicode" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| ) | ||||
|  | ||||
| func mavenExecuteIntegration(config mavenExecuteIntegrationOptions, _ *telemetry.CustomData) { | ||||
|   | ||||
| @@ -1,10 +1,11 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"strconv" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/maven" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| func mavenExecuteStaticCodeChecks(config mavenExecuteStaticCodeChecksOptions, telemetryData *telemetry.CustomData) { | ||||
|   | ||||
| @@ -2,14 +2,15 @@ package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	piperhttp "github.com/SAP/jenkins-library/pkg/http" | ||||
| 	"github.com/pkg/errors" | ||||
|  | ||||
| 	b64 "encoding/base64" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
|   | ||||
| @@ -8,13 +8,14 @@ import ( | ||||
| 	"encoding/base64" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"path" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/config" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperenv" | ||||
| 	"github.com/spf13/cobra" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"path" | ||||
| ) | ||||
|  | ||||
| // ReadPipelineEnv reads the commonPipelineEnvironment from disk and outputs it as JSON | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestCpeEncryption(t *testing.T) { | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package cmd | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
|   | ||||
| @@ -2,9 +2,10 @@ package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/spf13/cobra" | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| // GitCommit ... | ||||
|   | ||||
| @@ -308,7 +308,7 @@ func checkAndReportScanResults(ctx context.Context, config *ScanOptions, scan *w | ||||
| 	} | ||||
|  | ||||
| 	if len(checkErrors) > 0 { | ||||
| 		return reportPaths, fmt.Errorf(strings.Join(checkErrors, ": ")) | ||||
| 		return reportPaths, errors.New(strings.Join(checkErrors, ": ")) | ||||
| 	} | ||||
| 	return reportPaths, nil | ||||
| } | ||||
| @@ -674,7 +674,7 @@ func checkSecurityViolations(ctx context.Context, config *ScanOptions, scan *ws. | ||||
| 		log.Entry().Debugf("Aggregated %v alerts for scanned projects", len(allAlerts)) | ||||
| 	} | ||||
|  | ||||
| 	reportPaths, errors := reportGitHubIssuesAndCreateReports( | ||||
| 	reportPaths, e := reportGitHubIssuesAndCreateReports( | ||||
| 		ctx, | ||||
| 		config, | ||||
| 		utils, | ||||
| @@ -686,13 +686,13 @@ func checkSecurityViolations(ctx context.Context, config *ScanOptions, scan *ws. | ||||
| 		vulnerabilitiesCount, | ||||
| 	) | ||||
|  | ||||
| 	allOccurredErrors = append(allOccurredErrors, errors...) | ||||
| 	allOccurredErrors = append(allOccurredErrors, e...) | ||||
|  | ||||
| 	if len(allOccurredErrors) > 0 { | ||||
| 		if vulnerabilitiesCount > 0 { | ||||
| 			log.SetErrorCategory(log.ErrorCompliance) | ||||
| 		} | ||||
| 		return reportPaths, fmt.Errorf(strings.Join(allOccurredErrors, ": ")) | ||||
| 		return reportPaths, errors.New(strings.Join(allOccurredErrors, ": ")) | ||||
| 	} | ||||
|  | ||||
| 	return reportPaths, nil | ||||
|   | ||||
| @@ -8,11 +8,12 @@ import ( | ||||
| 	b64 "encoding/base64" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"github.com/SAP/jenkins-library/pkg/config" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/config" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperenv" | ||||
| 	"github.com/spf13/cobra" | ||||
|   | ||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @@ -22,6 +22,7 @@ require ( | ||||
| 	github.com/buildpacks/lifecycle v0.18.4 | ||||
| 	github.com/cloudevents/sdk-go/v2 v2.10.1 | ||||
| 	github.com/docker/cli v24.0.6+incompatible | ||||
| 	github.com/docker/docker v24.0.7+incompatible | ||||
| 	github.com/evanphx/json-patch v5.7.0+incompatible | ||||
| 	github.com/getsentry/sentry-go v0.26.0 | ||||
| 	github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 | ||||
| @@ -159,7 +160,6 @@ require ( | ||||
| 	github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect | ||||
| 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect | ||||
| 	github.com/docker/distribution v2.8.3+incompatible // indirect | ||||
| 	github.com/docker/docker v24.0.7+incompatible // indirect | ||||
| 	github.com/docker/docker-credential-helpers v0.8.0 // indirect | ||||
| 	github.com/docker/go-connections v0.4.0 // indirect | ||||
| 	github.com/docker/go-metrics v0.0.1 // indirect | ||||
|   | ||||
| @@ -7,50 +7,76 @@ import ( | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/docker/cli/cli/config/configfile" | ||||
| 	"github.com/docker/cli/cli/config/types" | ||||
| 	"github.com/docker/docker/registry" | ||||
| ) | ||||
|  | ||||
| func GenerateCnbAuth(config string, utils BuildUtils) (string, error) { | ||||
| 	var err error | ||||
| 	dockerConfig := &configfile.ConfigFile{} | ||||
| type DockerKeychain struct { | ||||
| 	dockerConfig *configfile.ConfigFile | ||||
| } | ||||
|  | ||||
| func (dk *DockerKeychain) ToCNBString() (string, error) { | ||||
| 	if dk.dockerConfig == nil || len(dk.dockerConfig.GetAuthConfigs()) == 0 { | ||||
| 		return "{}", nil | ||||
| 	} | ||||
|  | ||||
| 	cnbAuth := map[string]string{} | ||||
| 	for reg, authConf := range dk.dockerConfig.GetAuthConfigs() { | ||||
| 		registryHostname := registry.ConvertToHostname(reg) | ||||
| 		log.Entry().Debugf("adding credentials for registry %q", registryHostname) | ||||
| 		if authConf.RegistryToken != "" { | ||||
| 			cnbAuth[registryHostname] = fmt.Sprintf("Bearer %s", authConf.RegistryToken) | ||||
|  | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if authConf.Auth != "" { | ||||
| 			cnbAuth[registryHostname] = fmt.Sprintf("Basic %s", authConf.Auth) | ||||
|  | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if authConf.Username == "" && authConf.Password == "" { | ||||
| 			log.Entry().Warnf("docker config.json contains empty credentials for registry %q. Either 'auth' or 'username' and 'password' have to be provided.", registryHostname) | ||||
|  | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		cnbAuth[registryHostname] = fmt.Sprintf("Basic %s", encodeAuth(authConf.Username, authConf.Password)) | ||||
| 	} | ||||
|  | ||||
| 	cnbAuthBytes, err := json.Marshal(&cnbAuth) | ||||
| 	return string(cnbAuthBytes), err | ||||
| } | ||||
|  | ||||
| func (dk *DockerKeychain) AuthExistsForImage(image string) bool { | ||||
| 	var empty types.AuthConfig | ||||
| 	conf, err := dk.dockerConfig.GetAuthConfig(registry.ConvertToHostname(image)) | ||||
| 	if err != nil { | ||||
| 		log.Entry().Errorf("failed to get auth config for the image %q, error: %s", image, err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	return conf != empty | ||||
| } | ||||
|  | ||||
| func ParseDockerConfig(config string, utils BuildUtils) (*DockerKeychain, error) { | ||||
| 	keychain := &DockerKeychain{ | ||||
| 		dockerConfig: &configfile.ConfigFile{}, | ||||
| 	} | ||||
| 	if config != "" { | ||||
| 		log.Entry().Debugf("using docker config file %q", config) | ||||
| 		dockerConfigJSON, err := utils.FileRead(config) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		err = json.Unmarshal(dockerConfigJSON, dockerConfig) | ||||
| 		err = json.Unmarshal(dockerConfigJSON, keychain.dockerConfig) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	auth := map[string]string{} | ||||
| 	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 | ||||
| 		} | ||||
|  | ||||
| 		if value.Auth == "" { | ||||
| 			value.Auth = encodeAuth(value.Username, value.Password) | ||||
| 		} | ||||
|  | ||||
| 		log.Entry().Debugf("Adding credentials for: registry %q", registry) | ||||
| 		auth[registry] = fmt.Sprintf("Basic %s", value.Auth) | ||||
| 	} | ||||
|  | ||||
| 	if len(auth) == 0 { | ||||
| 		log.Entry().Warn("docker config file is empty!") | ||||
| 	} | ||||
|  | ||||
| 	cnbRegistryAuth, err := json.Marshal(auth) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return string(cnbRegistryAuth), nil | ||||
| 	return keychain, nil | ||||
| } | ||||
|  | ||||
| func encodeAuth(username, password string) string { | ||||
|   | ||||
| @@ -18,41 +18,61 @@ func TestGenerateCnbAuth(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	t.Run("successfully generates cnb auth env variable", func(t *testing.T) { | ||||
| 		mockUtils.AddFile("/test/valid_config.json", []byte("{\"auths\":{\"example.com\":{\"auth\":\"dXNlcm5hbWU6cGFzc3dvcmQ=\"}}}")) | ||||
| 		auth, err := cnbutils.GenerateCnbAuth("/test/valid_config.json", mockUtils) | ||||
| 		mockUtils.AddFile("/test/valid_config.json", []byte("{\"auths\":{\"https://example.com/\":{\"auth\":\"dXNlcm5hbWU6cGFzc3dvcmQ=\"}}}")) | ||||
| 		auth, err := cnbutils.ParseDockerConfig("/test/valid_config.json", mockUtils) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, "{\"example.com\":\"Basic dXNlcm5hbWU6cGFzc3dvcmQ=\"}", auth) | ||||
|  | ||||
| 		authString, err := auth.ToCNBString() | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, "{\"example.com\":\"Basic dXNlcm5hbWU6cGFzc3dvcmQ=\"}", authString) | ||||
| 		assert.True(t, auth.AuthExistsForImage("example.com/foo/bar:123")) | ||||
| 		assert.False(t, auth.AuthExistsForImage("docker.io/foo/bar")) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("successfully generates cnb auth env variable from username and password", func(t *testing.T) { | ||||
| 		mockUtils.AddFile("/test/valid_config.json", []byte("{\"auths\":{\"example.com\":{\"username\":\"username\",\"password\":\"password\"}}}")) | ||||
| 		auth, err := cnbutils.GenerateCnbAuth("/test/valid_config.json", mockUtils) | ||||
| 		auth, err := cnbutils.ParseDockerConfig("/test/valid_config.json", mockUtils) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, "{\"example.com\":\"Basic dXNlcm5hbWU6cGFzc3dvcmQ=\"}", auth) | ||||
|  | ||||
| 		authString, err := auth.ToCNBString() | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, "{\"example.com\":\"Basic dXNlcm5hbWU6cGFzc3dvcmQ=\"}", authString) | ||||
| 		assert.True(t, auth.AuthExistsForImage("example.com/foo/bar:123")) | ||||
| 		assert.False(t, auth.AuthExistsForImage("docker.io/foo/bar")) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("skips registry with empty credentials", func(t *testing.T) { | ||||
| 		mockUtils.AddFile("/test/valid_config.json", []byte("{\"auths\":{\"example.com\":{}}}")) | ||||
| 		auth, err := cnbutils.GenerateCnbAuth("/test/valid_config.json", mockUtils) | ||||
| 		auth, err := cnbutils.ParseDockerConfig("/test/valid_config.json", mockUtils) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, "{}", auth) | ||||
|  | ||||
| 		authString, err := auth.ToCNBString() | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, "{}", authString) | ||||
| 		assert.False(t, auth.AuthExistsForImage("example.com/foo/bar:123")) | ||||
| 		assert.False(t, auth.AuthExistsForImage("docker.io/foo/bar")) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("successfully generates cnb auth env variable if docker config is not present", func(t *testing.T) { | ||||
| 		auth, err := cnbutils.GenerateCnbAuth("", mockUtils) | ||||
| 		auth, err := cnbutils.ParseDockerConfig("", mockUtils) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, "{}", auth) | ||||
|  | ||||
| 		authString, err := auth.ToCNBString() | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, "{}", authString) | ||||
| 		assert.False(t, auth.AuthExistsForImage("example.com/foo/bar:123")) | ||||
| 		assert.False(t, auth.AuthExistsForImage("docker.io/foo/bar")) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("fails if file not found", func(t *testing.T) { | ||||
| 		_, err := cnbutils.GenerateCnbAuth("/not/found", mockUtils) | ||||
| 		_, err := cnbutils.ParseDockerConfig("/not/found", mockUtils) | ||||
| 		assert.Error(t, err) | ||||
| 		assert.Equal(t, "could not read '/not/found'", err.Error()) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("fails if file is invalid json", func(t *testing.T) { | ||||
| 		mockUtils.AddFile("/test/invalid_config.json", []byte("not a json")) | ||||
| 		_, err := cnbutils.GenerateCnbAuth("/test/invalid_config.json", mockUtils) | ||||
| 		_, err := cnbutils.ParseDockerConfig("/test/invalid_config.json", mockUtils) | ||||
| 		assert.Error(t, err) | ||||
| 		assert.Equal(t, "invalid character 'o' in literal null (expecting 'u')", err.Error()) | ||||
| 	}) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user