Skip to content

Commit

Permalink
feat(controller): use imagePullSecrets from ServiceAccounts
Browse files Browse the repository at this point in the history
  • Loading branch information
plaffitt committed Nov 22, 2023
1 parent 3ea99e5 commit 36ed728
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
26 changes: 26 additions & 0 deletions controllers/pod_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
log.Info("reconciling pod")

cachedImages := desiredCachedImages(ctx, &pod)
serviceAccountImagePullSecrets, err := r.imagePullSecretNamesFromPodServiceAccount(ctx, &pod)
if err != nil {
return ctrl.Result{}, err
}

// On pod deletion
if !pod.DeletionTimestamp.IsZero() {
Expand All @@ -81,6 +85,8 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
continue
}

cachedImage.Spec.PullSecretNames = append(cachedImage.Spec.PullSecretNames, serviceAccountImagePullSecrets...)

// Create or update CachedImage depending on weather it already exists or not
if apierrors.IsNotFound(err) {
err = r.Create(ctx, &cachedImage)
Expand Down Expand Up @@ -242,3 +248,23 @@ func cachedImageFromSourceImage(sourceImage string) (*kuikenixiov1alpha1.CachedI

return &cachedImage, nil
}

func (r *PodReconciler) imagePullSecretNamesFromPodServiceAccount(ctx context.Context, pod *corev1.Pod) ([]string, error) {
if pod.Spec.ServiceAccountName == "" {
return []string{}, nil
}

var serviceAccount corev1.ServiceAccount
serviceAccountNamespacedName := types.NamespacedName{Namespace: pod.Namespace, Name: pod.Spec.ServiceAccountName}
if err := r.Get(ctx, serviceAccountNamespacedName, &serviceAccount); err != nil {
return []string{}, err
}

imagePullSecretNames := make([]string, len(serviceAccount.ImagePullSecrets))

for i, imagePullSecret := range serviceAccount.ImagePullSecrets {
imagePullSecretNames[i] = imagePullSecret.Name
}

return imagePullSecretNames, nil
}
37 changes: 37 additions & 0 deletions controllers/pod_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ var podStub = corev1.Pod{
},
}

var serviceAccountStub = corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: podStub.Namespace,
},
ImagePullSecrets: []corev1.LocalObjectReference{
{Name: "service-account-pull-secret"},
{Name: "service-account-pull-secret-2"},
},
}

var podStubNotRewritten = corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Expand Down Expand Up @@ -156,6 +167,10 @@ var _ = Describe("Pod Controller", func() {
Expect(k8sClient.Delete(context.Background(), &podStub)).Should(suceedOrNotFound)
Expect(k8sClient.Delete(context.Background(), &podStubNotRewritten)).Should(suceedOrNotFound)

// allow to reuse the stub
podStub.ResourceVersion = ""
podStubNotRewritten.ResourceVersion = ""

By("Deleting all cached images")
Expect(k8sClient.DeleteAllOf(context.Background(), &kuikenixiov1alpha1.CachedImage{})).Should(Succeed())
})
Expand Down Expand Up @@ -205,5 +220,27 @@ var _ = Describe("Pod Controller", func() {
return fetched.Items
}, timeout, interval).Should(HaveLen(0))
})
It("Should create CachedImages with imagePullSecrets from Pod's ServiceAccount", func() {
By("Creating a Pod with a ServiceAccount")
Expect(k8sClient.Create(context.Background(), &serviceAccountStub)).Should(Succeed())

podStub.Spec.ServiceAccountName = serviceAccountStub.Name
Expect(k8sClient.Create(context.Background(), &podStub)).Should(Succeed())

fetched := &kuikenixiov1alpha1.CachedImageList{}
Eventually(func() []kuikenixiov1alpha1.CachedImage {
_ = k8sClient.List(context.Background(), fetched)
return fetched.Items
}, timeout, interval).Should(HaveLen(len(podStub.Spec.Containers) + len(podStub.Spec.InitContainers)))

imagePullSecretNames := make([]string, len(serviceAccountStub.ImagePullSecrets))
for i, imagePullSecretName := range serviceAccountStub.ImagePullSecrets {
imagePullSecretNames[i] = imagePullSecretName.Name
}

for _, cachedImage := range fetched.Items {
Expect(cachedImage.Spec.PullSecretNames).Should(ContainElements(imagePullSecretNames))
}
})
})
})
1 change: 1 addition & 0 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ var _ = BeforeSuite(func() {

err = (&CachedImageReconciler{
Client: k8sManager.GetClient(),
ApiReader: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
Recorder: k8sManager.GetEventRecorderFor("cachedimage-controller"),
ExpiryDelay: 1 * time.Hour,
Expand Down
7 changes: 7 additions & 0 deletions helm/kube-image-keeper/templates/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ rules:
- patch
- update
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- list
- watch
- apiGroups:
- ""
resources:
Expand Down

0 comments on commit 36ed728

Please sign in to comment.