Skip to content

Commit 7260b73

Browse files
committed
Add imagePullSecrets change
1 parent c21732b commit 7260b73

File tree

12 files changed

+209
-5
lines changed

12 files changed

+209
-5
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [0.9.0] - 2025-03-20
8+
### Added
9+
- Add imagePullSecrets update when an image is modified
10+
711
## [0.8.1] - 2025-03-17
812
### Fixed
913
- Fixed chart pdb rendering

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ DOCKER_BUILDX_BUILDER ?= "harbor-container-webhook"
1717
all: $(addprefix build-,$(ARCH))
1818

1919
# Image registry for build/push image targets
20-
IMAGE_REGISTRY ?= ghcr.io/indeedeng/harbor-container-webhook
20+
IMAGE_REGISTRY ?= harbor.monitoring-lz800.mindee.net/mindee/harbor-container-webhook
2121

2222
HELM_DIR ?= deploy/charts/harbor-container-webhook
2323

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ reference which matches at least one match rule and none of the exclusion rules,
4444
by the `replace` contents of the rule. If `checkUpstream` is enabled, the webhook will first fetch the manifest
4545
the rewritten container image reference and verify it exists before rewriting the image.
4646

47+
You can also update the `imagePullSecrets` of a modified pod to have the right docker secret to connect to the modified registry. For that, put `replaceImagePullSecrets` to `true` and be sure that `authSecretName` is set with the Kubernetes secret that you want to add to `imagePullSecrets`. If `imagePullSecrets` already contains a secret, the `authSecretName` will be added to the list anyway.
48+
4749
Example configuration:
4850
```yaml
4951
port: 9443
@@ -67,6 +69,12 @@ rules:
6769
replace: 'harbor.example.com/ubuntu-proxy'
6870
checkUpstream: true # tests if the manifest for the rewritten image exists
6971
authSecretName: harbor-example-image-pull-secret # optional, defaults to "" - secret in the webhook namespace for authenticating to harbor.example.com
72+
- name: 'docker.io rewrite rule with imagePullSecrets update'
73+
matches:
74+
- '^docker.io'
75+
replace: 'harbor.example.com/dockerhub-proxy'
76+
replaceImagePullSecrets: true # enable imagePullSecrets change for modified images
77+
authSecretName: harbor-example-image-pull-secret # secret to add to imagePullSecrets on the modified pod
7078
```
7179
Local Development
7280
===

deploy/charts/harbor-container-webhook/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: harbor-container-webhook
33
description: Webhook to configure pods with harbor proxy cache projects
44
type: application
55
version: 0.8.1
6-
appVersion: "0.8.0"
6+
appVersion: "0.9.0"
77
kubeVersion: ">= 1.16.0-0"
88
home: https://github.com/IndeedEng/harbor-container-webhook
99
maintainers:

deploy/charts/harbor-container-webhook/values.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ rules: []
113113
# platforms: # defaults to linux/amd64, only used if checkUpstream is set
114114
# - linux/amd64
115115
# - linux/arm64
116+
# - name: 'docker.io rewrite rule with imagePullSecrets update'
117+
# matches:
118+
# - '^docker.io'
119+
# replace: 'harbor.example.com/dockerhub-proxy'
120+
# replaceImagePullSecrets: true # enable imagePullSecrets change for modified images
121+
# authSecretName: harbor-example-image-pull-secret # secret to add to imagePullSecrets on the modified pod
116122

117123
extraRules: []
118124

hack/config.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,11 @@ rules:
1818
- '^docker.io/(library/)?ubuntu:.*$'
1919
replace: 'harbor-v2.awscmhqa2.k8s.indeed.tech/dockerhub-proxy-auth'
2020
checkUpstream: true # tests if the manifest for the rewritten image exists
21-
authSecretName: "harborv2-qa"
21+
authSecretName: "harborv2-qa"
22+
- name: 'docker.io rewrite rule with imagePullSecret change'
23+
# image refs must match at least one of the rules, and not match any excludes
24+
matches:
25+
- '^docker.io'
26+
replace: 'harbor.example.com/dockerhub-proxy'
27+
authSecretName: "harborv2-qa"
28+
replaceImagePullSecrets: true

hack/test/admission.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
"metadata": {
1414
},
1515
"spec": {
16+
"imagePullSecrets": [
17+
{
18+
"name": "foo"
19+
}
20+
],
1621
"containers": [
1722
{
1823
"name": "foo",

hack/test/no-op.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
"metadata": {
1414
},
1515
"spec": {
16+
"imagePullSecrets": [
17+
{
18+
"name": "foo"
19+
}
20+
],
1621
"containers": [
1722
{
1823
"name": "foo",

internal/config/config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,13 @@ type ProxyRule struct {
7979
// If the webhook lacks permissions to fetch the image manifest or the registry is down, the image
8080
// will not be rewritten. Experimental.
8181
CheckUpstream bool `yaml:"checkUpstream"`
82+
// ReplaceImagePullSecrets enables the replacement of the imagePullSecrets of the pod in addition to the image
83+
ReplaceImagePullSecrets bool `yaml:"replaceImagePullSecrets"`
8284
// List of the required platforms to check for if CheckUpstream is set. Defaults to "linux/amd64" if unset.
8385
Platforms []string `yaml:"platforms"`
8486
// AuthSecretName is a reference to an image pull secret (must be .dockerconfigjson type) which
85-
// will be used to authenticate if `checkUpstream` is set. Unused if not specified or `checkUpstream` is false.
87+
// will be used to authenticate if `checkUpstream` is set or to modify the imagePullSecrets if
88+
// `replaceImagePullSecrets` is set.
8689
AuthSecretName string `yaml:"authSecretName"`
8790
// Namespace that the webhook is running in, used for accessing secrets for authenticated proxy rules
8891
Namespace string

internal/webhook/mutate.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func (p *PodContainerProxier) Handle(ctx context.Context, req admission.Request)
3838
return admission.Errored(http.StatusBadRequest, err)
3939
}
4040

41+
// container images
4142
initContainers, updatedInit, err := p.updateContainers(ctx, pod.Spec.InitContainers, "init")
4243
if err != nil {
4344
return admission.Errored(http.StatusInternalServerError, err)
@@ -52,6 +53,16 @@ func (p *PodContainerProxier) Handle(ctx context.Context, req admission.Request)
5253
pod.Spec.InitContainers = initContainers
5354
pod.Spec.Containers = containers
5455

56+
// imagePullSecrets
57+
imagePullSecrets, updatedImagePullSecrets, err := p.updateImagePullSecrets(pod.Spec.ImagePullSecrets)
58+
if err != nil {
59+
return admission.Errored(http.StatusInternalServerError, err)
60+
}
61+
if !updatedImagePullSecrets {
62+
return admission.Allowed("no updates")
63+
}
64+
pod.Spec.ImagePullSecrets = imagePullSecrets
65+
5566
marshaledPod, err := json.Marshal(pod)
5667
if err != nil {
5768
return admission.Errored(http.StatusInternalServerError, err)
@@ -68,7 +79,7 @@ func (p *PodContainerProxier) lookupNodeArchAndOS(ctx context.Context, restClien
6879
return node.Status.NodeInfo.Architecture, node.Status.NodeInfo.OperatingSystem, nil
6980
}
7081

71-
func (p *PodContainerProxier) updateContainers(ctx context.Context, containers []corev1.Container, kind string) ([]corev1.Container, bool, error) {
82+
func (p *PodContainerProxier) updateContainers(ctx context.Context, containers []corev1.Container, _ string) ([]corev1.Container, bool, error) {
7283
containersReplacement := make([]corev1.Container, 0, len(containers))
7384
updated := false
7485
for i := range containers {
@@ -118,3 +129,15 @@ func (p *PodContainerProxier) InjectDecoder(d admission.Decoder) error {
118129
p.Decoder = d
119130
return nil
120131
}
132+
133+
func (p *PodContainerProxier) updateImagePullSecrets(imagePullSecrets []corev1.LocalObjectReference) (newImagePullSecrets []corev1.LocalObjectReference, updated bool, err error) {
134+
pod := &corev1.Pod{}
135+
for _, transformer := range p.Transformers {
136+
updated, newImagePullSecrets, err = transformer.RewriteImagePullSecrets(imagePullSecrets)
137+
if err != nil {
138+
return imagePullSecrets, false, err
139+
}
140+
logger.Info(fmt.Sprintf("rewriting the imagePullSecrets of the pod %q from %q to %q", pod.ObjectMeta.Name, imagePullSecrets, newImagePullSecrets))
141+
}
142+
return newImagePullSecrets, updated, nil
143+
}

0 commit comments

Comments
 (0)