Skip to content

Commit

Permalink
fix: add support for legacy .dockercfg
Browse files Browse the repository at this point in the history
close #26

Signed-off-by: Christian Kotzbauer <[email protected]>
  • Loading branch information
ckotzbauer committed Feb 3, 2022
1 parent be0b3ef commit 92c41c6
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 20 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/test-registries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,19 @@ jobs:
--docker-email="${{ secrets.TEST_EMAIL }}" \
-o json --dry-run=client | jq -r '.data.".dockerconfigjson"' > auth/hub.yaml
- name: Prepare legacy Hub secrets
shell: bash
run: |
cat << EOF > .dockercfg
{
"https://index.docker.io/v1/": { "username": "${{ secrets.TEST_HUB_USERNAME }}", "password": "${{ secrets.TEST_HUB_PASSWORD }}" }
}
EOF
kubectl create secret generic hub-secret \
--from-file=.dockercfg \
--type=kubernetes.io/dockercfg \
-o json --dry-run=client | jq -r '.data.".dockercfg"' > auth/legacy-hub.yaml
- name: Execute Registry-Tests
run: make test-registries
31 changes: 20 additions & 11 deletions internal/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import (
)

type ContainerImage struct {
Image string
ImageID string
Auth []byte
Pods []corev1.Pod
Image string
ImageID string
Auth []byte
LegacyAuth bool
Pods []corev1.Pod
}

type KubeClient struct {
Expand Down Expand Up @@ -95,7 +96,7 @@ func (client *KubeClient) LoadImageInfos(namespaces []corev1.Namespace, podLabel
statuses = append(statuses, pod.Status.InitContainerStatuses...)
statuses = append(statuses, pod.Status.EphemeralContainerStatuses...)

pullSecrets, err := client.loadSecrets(pod.Namespace, pod.Spec.ImagePullSecrets)
pullSecrets, legacy, err := client.loadSecrets(pod.Namespace, pod.Spec.ImagePullSecrets)

if err != nil {
logrus.WithError(err).Errorf("PullSecrets could not be retrieved for pod %s/%s", ns.Name, pod.Name)
Expand All @@ -107,7 +108,13 @@ func (client *KubeClient) LoadImageInfos(namespaces []corev1.Namespace, podLabel
if !client.hasAnnotation(annotations, c) {
img, ok := images[c.ImageID]
if !ok {
img = ContainerImage{Image: c.Image, ImageID: c.ImageID, Auth: pullSecrets, Pods: []corev1.Pod{}}
img = ContainerImage{
Image: c.Image,
ImageID: c.ImageID,
Auth: pullSecrets,
LegacyAuth: legacy,
Pods: []corev1.Pod{},
}
}

img.Pods = append(img.Pods, pod)
Expand Down Expand Up @@ -173,28 +180,30 @@ func (client *KubeClient) hasAnnotation(annotations map[string]string, status co
return false
}

func (client *KubeClient) loadSecrets(namespace string, secrets []corev1.LocalObjectReference) ([]byte, error) {
func (client *KubeClient) loadSecrets(namespace string, secrets []corev1.LocalObjectReference) ([]byte, bool, error) {
// TODO: Support all secrets which are referenced as imagePullSecrets instead of only the first one.
for _, s := range secrets {
secret, err := client.Client.CoreV1().Secrets(namespace).Get(context.Background(), s.Name, meta.GetOptions{})
if err != nil {
return nil, err
return nil, false, err
}

var creds []byte
legacy := false

if secret.Type == corev1.SecretTypeDockerConfigJson {
creds = secret.Data[corev1.DockerConfigJsonKey]
} else if secret.Type == corev1.SecretTypeDockercfg {
creds = secret.Data[corev1.DockerConfigKey]
legacy = true
} else {
return nil, fmt.Errorf("invalid secret-type %s for pullSecret %s/%s", secret.Type, secret.Namespace, secret.Name)
return nil, false, fmt.Errorf("invalid secret-type %s for pullSecret %s/%s", secret.Type, secret.Namespace, secret.Name)
}

if len(creds) > 0 {
return creds, nil
return creds, legacy, nil
}
}

return nil, nil
return nil, false, nil
}
12 changes: 11 additions & 1 deletion internal/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/config/types"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/crane"
Expand All @@ -23,7 +24,16 @@ func SaveImage(imagePath string, image kubernetes.ContainerImage) error {
o := crane.GetOptions()

if len(image.Auth) > 0 {
cf, err := config.LoadFromReader(bytes.NewReader(image.Auth))
var cf *configfile.ConfigFile
var err error

if image.LegacyAuth {
cf = configfile.New("")
err = cf.LegacyLoadFromReader(bytes.NewReader(image.Auth))
} else {
cf, err = config.LoadFromReader(bytes.NewReader(image.Auth))
}

if err != nil {
return err
}
Expand Down
22 changes: 14 additions & 8 deletions internal/registry/registry_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ func TestRegistry(t *testing.T) {
RunSpecs(t, "Registry Suite")
}

func testRegistry(name, image string) {
func testRegistry(name, image string, legacy bool) {
b, err := os.ReadFile("../../auth/" + name + ".yaml")
Expect(err).To(BeNil())

decoded, err := base64.StdEncoding.DecodeString(string(b))
Expect(err).To(BeNil())

file := "/tmp/1.0.0.tar.gz"
err = registry.SaveImage(file, kubernetes.ContainerImage{ImageID: image, Auth: []byte(decoded)})
err = registry.SaveImage(file, kubernetes.ContainerImage{ImageID: image, Auth: []byte(decoded), LegacyAuth: legacy})

if err == nil {
stat, _ := os.Stat(file)
Expand All @@ -38,37 +38,43 @@ func testRegistry(name, image string) {
var _ = Describe("Registry", func() {
Describe("Storing image from GCR", func() {
It("should work correctly", func() {
testRegistry("gcr", "gcr.io/sbom-git-operator/integration-test-image:1.0.0")
testRegistry("gcr", "gcr.io/sbom-git-operator/integration-test-image:1.0.0", false)
})
})

Describe("Storing image from GAR", func() {
It("should work correctly", func() {
testRegistry("gar", "europe-west3-docker.pkg.dev/sbom-git-operator/sbom-git-operator/integration-test-image:1.0.0")
testRegistry("gar", "europe-west3-docker.pkg.dev/sbom-git-operator/sbom-git-operator/integration-test-image:1.0.0", false)
})
})

Describe("Storing image from ECR", func() {
It("should work correctly", func() {
testRegistry("ecr", "055403865123.dkr.ecr.eu-central-1.amazonaws.com/sbom-git-operator/integration-test-image:1.0.0")
testRegistry("ecr", "055403865123.dkr.ecr.eu-central-1.amazonaws.com/sbom-git-operator/integration-test-image:1.0.0", false)
})
})

Describe("Storing image from ACR", func() {
It("should work correctly", func() {
testRegistry("acr", "sbomgitoperator.azurecr.io/integration-test-image:1.0.0")
testRegistry("acr", "sbomgitoperator.azurecr.io/integration-test-image:1.0.0", false)
})
})

Describe("Storing image from DockerHub", func() {
It("should work correctly", func() {
testRegistry("hub", "docker.io/ckotzbauer/integration-test-image:1.0.0")
testRegistry("hub", "docker.io/ckotzbauer/integration-test-image:1.0.0", false)
})
})

Describe("Storing image from GHCR", func() {
It("should work correctly", func() {
testRegistry("ghcr", "ghcr.io/ckotzbauer-kubernetes-bot/sbom-git-operator-integration-test:1.0.0")
testRegistry("ghcr", "ghcr.io/ckotzbauer-kubernetes-bot/sbom-git-operator-integration-test:1.0.0", false)
})
})

Describe("Storing image from DockerHub - legacy .dockercfg", func() {
It("should work correctly", func() {
testRegistry("legacy-hub", "docker.io/ckotzbauer/integration-test-image:1.0.0", true)
})
})
})

0 comments on commit 92c41c6

Please sign in to comment.