Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

delay start of controller until resource is found #3047

Open
jvrahav opened this issue Dec 26, 2024 · 1 comment
Open

delay start of controller until resource is found #3047

jvrahav opened this issue Dec 26, 2024 · 1 comment

Comments

@jvrahav
Copy link

jvrahav commented Dec 26, 2024

Is there a way to delay start of a controller until a resource exists in the apiserver.

Say i want to watch resource types A and B. However i want to do this only after some other process has created a resource of resource type C

I need this to avoid watching for resources until a dependent resource exists in the system, resource of type C. This way i can ensure my controller is not consuming resources unless it is required.

Thanks,
Rahav

@whg517
Copy link
Contributor

whg517 commented Dec 31, 2024

I think you can customize the coordinator's SetupWithManager method to trigger the resources that need to be coordinated while listening for the required resource changes.

example code :

// SetupWithManager sets up the controller with the Manager.
func (r *ListenerReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&listeners.Listener{}).
		Watches(&corev1.Endpoints{}, handler.TypedEnqueueRequestsFromMapFunc(r.handleEndpointsChanges)).
		Watches(&corev1.PersistentVolume{}, handler.EnqueueRequestsFromMapFunc(r.handlePVChanges)).
		Watches(&listeners.ListenerClass{}, handler.EnqueueRequestsFromMapFunc(r.handleListenerClassChanges)).
		Complete(r)
}

func (r *ListenerReconciler) handleListenerClassChanges(ctx context.Context, obj client.Object) []ctrl.Request {
	listenerClass := obj.(*listeners.ListenerClass)
	list := &listeners.ListenerList{}
	if err := r.List(ctx, list); err != nil {
		return nil
	}

	requests := make([]ctrl.Request, 0)
	for _, listener := range list.Items {
		if listener.Spec.ClassName == listenerClass.Name {
			requests = append(requests, reconcile.Request{
				NamespacedName: client.ObjectKey{
					Name:      listener.Name,
					Namespace: listener.Namespace,
				},
			})
		}
	}

	return requests
}

func (r *ListenerReconciler) handleEndpointsChanges(ctx context.Context, obj client.Object) []ctrl.Request {
	endpoints := obj.(*corev1.Endpoints)
	list := &listeners.ListenerList{}
	if err := r.List(ctx, list); err != nil {
		return nil
	}

	requests := make([]ctrl.Request, 0)
	for _, listener := range list.Items {
		if listener.Status.ServiceName == endpoints.Name {
			requests = append(requests, reconcile.Request{
				NamespacedName: client.ObjectKey{
					Name:      listener.Name,
					Namespace: listener.Namespace,
				},
			})
		}
	}

	return requests
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants