@@ -2,11 +2,15 @@ package core
22
33import (
44 "context"
5+ "os"
6+ "strconv"
57 "strings"
8+ "time"
69
710 kuikv1alpha1 "github.com/enix/kube-image-keeper/api/kuik/v1alpha1"
811 corev1 "k8s.io/api/core/v1"
912 apierrors "k8s.io/apimachinery/pkg/api/errors"
13+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1014 "k8s.io/apimachinery/pkg/runtime"
1115 "k8s.io/klog/v2"
1216 ctrl "sigs.k8s.io/controller-runtime"
@@ -19,13 +23,15 @@ import (
1923)
2024
2125const (
22- PodImagesIndexKey = ".metadata.images "
26+ RegistryIndexKey = ".spec.registry "
2327)
2428
2529// PodReconciler reconciles a Pod object
2630type PodReconciler struct {
2731 client.Client
2832 Scheme * runtime.Scheme
33+
34+ defaultRegistryMonitorSpec kuikv1alpha1.RegistryMonitorSpec
2935}
3036
3137// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch
@@ -68,6 +74,27 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
6874 continue
6975 }
7076
77+ var registryMonitors kuikv1alpha1.RegistryMonitorList
78+ if err := r .List (ctx , & registryMonitors , client.MatchingFields {
79+ RegistryIndexKey : image .Spec .Registry ,
80+ }); err != nil {
81+ return ctrl.Result {}, err
82+ }
83+ if len (registryMonitors .Items ) == 0 {
84+ log .Info ("no registry monitor found for image, creating one with default values" , "image" , klog .KObj (& image ), "registry" , image .Spec .Registry )
85+ spec := r .defaultRegistryMonitorSpec .DeepCopy ()
86+ spec .Registry = image .Spec .Registry
87+ err := r .Create (ctx , & kuikv1alpha1.RegistryMonitor {
88+ ObjectMeta : metav1.ObjectMeta {
89+ Name : image .Spec .Registry ,
90+ },
91+ Spec : * spec ,
92+ })
93+ if err != nil {
94+ return ctrl.Result {}, err
95+ }
96+ }
97+
7198 // create or update Image depending on weather it already exists or not
7299 if apierrors .IsNotFound (err ) {
73100 log .Info ("new image found on a pod" , "image" , klog .KObj (& image ))
@@ -99,6 +126,43 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
99126
100127// SetupWithManager sets up the controller with the Manager.
101128func (r * PodReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
129+ // create an index to list RegistryMonitors by registry
130+ if err := mgr .GetFieldIndexer ().IndexField (context .Background (), & kuikv1alpha1.RegistryMonitor {}, RegistryIndexKey , func (rawObj client.Object ) []string {
131+ image := rawObj .(* kuikv1alpha1.RegistryMonitor )
132+
133+ return []string {image .Spec .Registry }
134+ }); err != nil {
135+ return err
136+ }
137+
138+ r .defaultRegistryMonitorSpec = kuikv1alpha1.RegistryMonitorSpec {
139+ Interval : metav1.Duration {Duration : 10 * time .Minute },
140+ MaxPerInterval : 1 ,
141+ Parallel : 1 ,
142+ }
143+
144+ if env := os .Getenv ("KUIK_REGISTRY_MONITOR_DEFAULT_INTERVAL" ); env != "" {
145+ interval , err := time .ParseDuration (env )
146+ if err != nil {
147+ return err
148+ }
149+ r .defaultRegistryMonitorSpec .Interval = metav1.Duration {Duration : interval }
150+ }
151+ if env := os .Getenv ("KUIK_REGISTRY_MONITOR_DEFAULT_MAX_PER_INTERVAL" ); env != "" {
152+ maxPerInterval , err := strconv .Atoi (env )
153+ if err != nil {
154+ return err
155+ }
156+ r .defaultRegistryMonitorSpec .MaxPerInterval = maxPerInterval
157+ }
158+ if env := os .Getenv ("KUIK_REGISTRY_MONITOR_DEFAULT_PARALLEL" ); env != "" {
159+ parallel , err := strconv .Atoi (env )
160+ if err != nil {
161+ return err
162+ }
163+ r .defaultRegistryMonitorSpec .Parallel = parallel
164+ }
165+
102166 p := predicate .Not (predicate.Funcs {
103167 DeleteFunc : func (e event.DeleteEvent ) bool {
104168 return false
0 commit comments