Skip to content

Commit

Permalink
fix: docker references with both tag and digest
Browse files Browse the repository at this point in the history
fix estahn#48

This solution is taken almost directly from CRI-O, as referenced here: https://github.com/cri-o/cri-o/pull/3060/files
  • Loading branch information
rattboi authored and estahn committed Jul 2, 2022
1 parent 6a8e12e commit 668cfbb
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
30 changes: 28 additions & 2 deletions pkg/webhook/image_swapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,26 @@ func NewImageSwapperWebhook(registryClient registry.Client, imagePullSecretProvi
return kwhmutating.NewWebhook(mcfg)
}

// imageNamesWithDigestOrTag strips the tag from ambiguous image references that have a digest as well (e.g. `image:tag@sha256:123...`).
// Such image references are supported by docker but, due to their ambiguity,
// explicitly not by containers/image.
func imageNamesWithDigestOrTag(imageName string) (string, error) {
ref, err := reference.ParseNormalizedNamed(imageName)
if err != nil {
return "", err
}
_, isTagged := ref.(reference.NamedTagged)
canonical, isDigested := ref.(reference.Canonical)
if isTagged && isDigested {
canonical, err = reference.WithDigest(reference.TrimNamed(ref), canonical.Digest())
if err != nil {
return "", err
}
imageName = canonical.String()
}
return imageName, nil
}

// Mutate replaces the image ref. Satisfies mutating.Mutator interface.
func (p *ImageSwapper) Mutate(ctx context.Context, ar *kwhmodel.AdmissionReview, obj metav1.Object) (*kwhmutating.MutatorResult, error) {
pod, ok := obj.(*corev1.Pod)
Expand All @@ -159,9 +179,15 @@ func (p *ImageSwapper) Mutate(ctx context.Context, ar *kwhmodel.AdmissionReview,
for _, containerSet := range containerSets {
containers := *containerSet
for i, container := range containers {
srcRef, err := alltransports.ParseImageName("docker://" + container.Image)
normalizedName, err := imageNamesWithDigestOrTag(container.Image)
if err != nil {
log.Ctx(lctx).Warn().Msgf("unable to normalize source name %s: %v", container.Image, err)
continue
}

srcRef, err := alltransports.ParseImageName("docker://" + normalizedName)
if err != nil {
log.Ctx(lctx).Warn().Msgf("invalid source name %s: %v", container.Image, err)
log.Ctx(lctx).Warn().Msgf("invalid source name %s: %v", normalizedName, err)
continue
}

Expand Down
16 changes: 15 additions & 1 deletion pkg/webhook/image_swapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,19 @@ func TestImageSwapper_Mutate(t *testing.T) {
Value: aws.String("k8s-image-swapper"),
}},
}).Return(mock.Anything)
ecrClient.On(
"CreateRepository",
&ecr.CreateRepositoryInput{
ImageScanningConfiguration: &ecr.ImageScanningConfiguration{
ScanOnPush: aws.Bool(true),
},
ImageTagMutability: aws.String("MUTABLE"),
RepositoryName: aws.String("k8s.gcr.io/ingress-nginx/controller"),
Tags: []*ecr.Tag{{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
}},
}).Return(mock.Anything)

registryClient, _ := registry.NewMockECRClient(ecrClient, "ap-southeast-2", "123456789.dkr.ecr.ap-southeast-2.amazonaws.com")

Expand All @@ -283,7 +296,8 @@ func TestImageSwapper_Mutate(t *testing.T) {

expected := `[
{"op":"replace","path":"/spec/initContainers/0/image","value":"123456789.dkr.ecr.ap-southeast-2.amazonaws.com/docker.io/library/init-container:latest"},
{"op":"replace","path":"/spec/containers/0/image","value":"123456789.dkr.ecr.ap-southeast-2.amazonaws.com/docker.io/library/nginx:latest"}
{"op":"replace","path":"/spec/containers/0/image","value":"123456789.dkr.ecr.ap-southeast-2.amazonaws.com/docker.io/library/nginx:latest"},
{"op":"replace","path":"/spec/containers/1/image","value":"123456789.dkr.ecr.ap-southeast-2.amazonaws.com/k8s.gcr.io/ingress-nginx/controller@sha256:9bba603b99bf25f6d117cf1235b6598c16033ad027b143c90fa5b3cc583c5713"}
]`

assert.JSONEq(t, expected, string(resp.(*model.MutatingAdmissionResponse).JSONPatchPatch))
Expand Down
15 changes: 15 additions & 0 deletions test/requests/admissionreview-simple.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@
"readOnly": true
}
]
},
{
"image": "k8s.gcr.io/ingress-nginx/controller:v0.43.0@sha256:9bba603b99bf25f6d117cf1235b6598c16033ad027b143c90fa5b3cc583c5713",
"imagePullPolicy": "Always",
"name": "ingress-nginx28",
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "default-token-fjtvr",
"readOnly": true
}
]
}
],
"dnsPolicy": "ClusterFirst",
Expand Down

0 comments on commit 668cfbb

Please sign in to comment.