Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
skylenet committed Oct 2, 2024
1 parent a6905b7 commit 961d487
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os/exec"
"strings"

"github.com/davecgh/go-spew/spew"
"github.com/docker/docker/api/types/registry"
dockerregistry "github.com/docker/docker/registry"
)
Expand Down Expand Up @@ -59,24 +60,45 @@ func getCredentialsFromStore(credHelper string, registryURL string) (*registry.A
return nil, fmt.Errorf("error executing credential helper %s: %v, %s", credHelperCmd, err, stderr.String())
}

// Parse the output (it should return JSON containing "Username" and "Secret")
var creds registry.AuthConfig
// Parse the output (it should return JSON containing "Username", "Secret" and "ServerURL")
creds := struct {
Username string `json:"Username"`
Secret string `json:"Secret"`
ServerURL string `json:"ServerURL"`
}{}

if err := json.Unmarshal(out.Bytes(), &creds); err != nil {
return nil, fmt.Errorf("error parsing credentials from store: %v", err)
}

return &creds, nil
return &registry.AuthConfig{

Check failure on line 74 in container-engine-lib/lib/backend_impls/docker/docker_manager/docker_auth.go

View workflow job for this annotation

GitHub Actions / golang-lint (container-engine-lib)

Auth, Email, IdentityToken, RegistryToken are missing in AuthConfig (exhaustruct)
Username: creds.Username,
Password: creds.Secret,
ServerAddress: creds.ServerURL,
}, nil
}

// getAuthFromDockerConfig retrieves the auth configuration for a given repository
func getAuthFromDockerConfig(repo string) (*registry.AuthConfig, error) {
// GetAuthFromDockerConfig retrieves the auth configuration for a given repository
// by checking the Docker config.json file and Docker credential helpers.
// Returns nil if no credentials were found.
func GetAuthFromDockerConfig(repo string) (*registry.AuthConfig, error) {
authConfig, err := loadDockerAuth()
if err != nil {
return nil, err
}

registryHost := dockerregistry.ConvertToHostname(repo)

spew.Dump(registryHost)
if !strings.Contains(registryHost, ".") || registryHost == "docker.io" || registryHost == "registry-1.docker.io" {
registryHost = "https://index.docker.io/v1/"
}

// Check if the URL contains "://", meaning it already has a protocol
if !strings.Contains(registryHost, "://") {
registryHost = "https://" + registryHost
}

// 1. Check if there is a credHelper for this specific registry
if credHelper, exists := authConfig.CredHelpers[registryHost]; exists {
return getCredentialsFromStore(credHelper, registryHost)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package docker_manager

import (
"encoding/base64"
"fmt"
"io/ioutil"

Check failure on line 6 in container-engine-lib/lib/backend_impls/docker/docker_manager/docker_auth_test.go

View workflow job for this annotation

GitHub Actions / golang-lint (container-engine-lib)

SA1019: "io/ioutil" has been deprecated since Go 1.19: As of Go 1.16, the same functionality is now provided by package io or package os, and those implementations should be preferred in new code. See the specific function documentation for details. (staticcheck)
"os"
"testing"

"github.com/docker/docker/api/types/registry"
"github.com/stretchr/testify/assert"
)

// WriteStaticConfig writes a static Docker config.json file to a temporary directory
func WriteStaticConfig(t *testing.T, configContent string) string {
tmpDir, err := os.MkdirTemp("", "docker-config")
if err != nil {
t.Fatalf("Failed to create temp directory: %v", err)
}

configPath := tmpDir + "/config.json"
err = ioutil.WriteFile(configPath, []byte(configContent), 0600)
if err != nil {
t.Fatalf("Failed to write config.json: %v", err)
}

// Set the DOCKER_CONFIG environment variable to the temp directory
os.Setenv("DOCKER_CONFIG", tmpDir)
return tmpDir
}

func TestGetAuthConfigForRepoPlain(t *testing.T) {
cfg := `
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "dXNlcjpwYXNzd29yZA=="
}
}
}
`
tmpDir := WriteStaticConfig(t, cfg)
defer os.RemoveAll(tmpDir)

expectedAuth := registry.AuthConfig{

Check failure on line 45 in container-engine-lib/lib/backend_impls/docker/docker_manager/docker_auth_test.go

View workflow job for this annotation

GitHub Actions / golang-lint (container-engine-lib)

Auth, Email, ServerAddress, IdentityToken, RegistryToken are missing in AuthConfig (exhaustruct)
Username: "user",
Password: "password",
}
encodedAuth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", expectedAuth.Username, expectedAuth.Password)))

// Test 1: Retrieve auth config for Docker Hub using docker.io domain
authConfig, err := GetAuthFromDockerConfig("docker.io/my-repo/my-image:latest")
assert.NoError(t, err)
assert.Equal(t, encodedAuth, authConfig.Auth, "Auth for Docker Hub should match")

// Test 2: Retrieve auth config for Docker Hub using no domain
authConfig, err = GetAuthFromDockerConfig("my-repo/my-image:latest")
assert.NoError(t, err)
assert.Equal(t, encodedAuth, authConfig.Auth, "Auth for Docker Hub should match when using no host prefix")

// Test 3: Retrieve auth config for Docker Hub using full domain and https:// prefix
authConfig, err = GetAuthFromDockerConfig("https://registry-1.docker.io/my-repo/my-image:latest")
assert.NoError(t, err)
assert.Equal(t, encodedAuth, authConfig.Auth, "Auth for Docker Hub should match when using no host prefix")

}

func TestGetAuthConfigForRepoOSX(t *testing.T) {
t.Skip("Skipping test that requires macOS keychain")

cfg := `{
"auths": {
"https://index.docker.io/v1/": {}
},
"credsStore": "osxkeychain"
}`
tmpDir := WriteStaticConfig(t, cfg)
defer os.RemoveAll(tmpDir)

authConfig, err := GetAuthFromDockerConfig("my-repo/my-image:latest")
assert.NoError(t, err)
assert.NotNil(t, authConfig, "Auth config should not be nil")
}
Original file line number Diff line number Diff line change
Expand Up @@ -2281,7 +2281,7 @@ func pullImage(dockerClient *client.Client, imageName string, registrySpec *imag
}

// Try to obtain the auth configuration from the docker config file
authConfig, err := getAuthFromDockerConfig(imageName)
authConfig, err := GetAuthFromDockerConfig(imageName)
if err != nil {
logrus.Errorf("An error occurred while getting auth config for image: %s: %s", imageName, err.Error())
}
Expand Down

0 comments on commit 961d487

Please sign in to comment.