<p>We have an k8s operator (based on kubebuilder) which works as expected, now we need support for listening to secrets on the cluster.</p>
<p>The following code is working however I got event for <strong>all the secrets</strong> in the cluster which is <strong>not efficient</strong>,</p>
<p>I WANT to get the event <strong>only for specific secret</strong>, lets say secret with specific <code>labels/annotation</code>, how we can do it?</p>
<pre><code>func (r *InvReconciler) SetupWithManager(mgr ctrl.Manager) error {
    manager := ctrl.NewControllerManagedBy(mgr).
        For(&amp;corev1alpha1.Inv{}, builder.WithPredicates(predicate.Or(predicate.GenerationChangedPredicate{}, predicate.AnnotationChangedPredicate{}))).
        WithOptions(controller.Options{
        })

    manager = manager.Watches(&amp;source.Kind{Type: &amp;v1.Secret{}}, handler.EnqueueRequestsFromMapFunc(func(a client.Object) []reconcile.Request {
        return r.secretHandler.GetSecret(a.GetNamespace(), a.GetName())
    }))

    return manager.Complete(r)
}
</code></pre>
<p>this is the function</p>
<pre><code>func (secretReq secretHandler) GetSecret(namespace string, name string) []reconcile.Request {

    fmt.Println(&quot;secret is: &quot;, namespace, &quot;--&quot;, name)
    return nil
}
</code></pre>
<p>lets say secret like the following and only for this secret (with labels <code>foo: bar</code> )i'll get the event when it was created or modified</p>
<pre><code>apiVersion: v1
kind: Secret
metadata:
  labels:
    foo: bar
  name: mysecret
  namespace: dev
type: Opaque
data:
  USER_NAME: YWRtaW4=
  PASSWORD: dGVzdBo=
</code></pre>
<p>Im <strong>not</strong> talking about an <code>if statement</code> after I got the event as it already bring all the secrets event in the cluster.</p>

<p>According to this <a href="https://github.com/operator-framework/operator-sdk/issues/694" rel="nofollow noreferrer">github</a> source, you should be able to select specific objects (e.g. secrets) with <code>EnqueueRequestForObject</code>. However, it is <strong>not</strong> possible (yet) to watch only for specific secret CRUD changes.</p>
<blockquote>
<p><strong>EnqueueRequestForObject</strong> to watch for your CRD resource changes. In
your CRD reconciler, you'd fetch all of the TLS secrets using a label
selector based on the search definition and then run your merge logic
with the matched secrets.</p>
<p><strong>EnqueueRequestFromMapFunc</strong> to watch for
secret changes and trigger a reconcile of one or more CRs. In your
mapper function, you'd fetch all of the CRs. For each CR that has a
search definition that matches the passed in secret, you'd create a
new reconcile.Request for the CR, and return the list of requests,
which would trigger your CRD reconciler for each CR that matched.</p>
</blockquote>
<p>The cleanest way is using a label selector and then merge the results with your existing code. An example of using a label selector is given in this <a href="https://stackoverflow.com/a/56356932/7950592">post</a>:</p>
<pre><code>func GetSecret(version string) (retVal interface{}, err error){
  clientset := GetClientOutOfCluster()
  labelSelector := metav1.LabelSelector{MatchLabels: map[string]string{&quot;version&quot;:version}}

  listOptions := metav1.ListOptions{
    LabelSelector: labels.Set(labelSelector.MatchLabels).String(),
    Limit:         100,
  }
  secretList, err := clientset.CoreV1().Secrets(&quot;namespace&quot;).List(listOptions)
  retVal = secretList.Items[0]
  return retVal, err
}
</code></pre>
