<p>I'm working on developing a k8s custom resource that as part of the business logic needs to reconcile its state when an external Job in the cluster have changed its own state.</p>
<p>Those Jobs aren't created by the custom resource itself but are externally created for a third party service, however I need to reconcile the state of the CRO for example when any of those external jobs have finished.</p>
<p>After reading bunch of documentation, I came up with setting a watcher for the controller, to watch Jobs like the following example</p>
<pre><code>func (r *DatasetReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&amp;datasetv1beta1.Dataset{}).
        Watches(&amp;source.Kind{Type: &amp;batchv1.Job{}}, &amp;handler.EnqueueRequestForObject{} /* filter by predicates, see https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.9.6/pkg/controller#Controller */).
        Complete(r)
}
</code></pre>
<p>No I'm having my reconcile loop triggered for Jobs and my CRs with the corresponding  <strong>name</strong> and <strong>namespace</strong> but I don't know anything about the object kind.</p>
<pre><code>func (r *DatasetReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    l := log.FromContext(ctx)
    l.Info(&quot;Enter Reconcile loop&quot;)
    l.Info(&quot;Request&quot;, &quot;Req&quot;, req)

    //if this is triggered by my CR
    dataset := &amp;datasetv1beta1.Dataset{}
    r.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, dataset)
    //whereas when triggered by a Job
    job := &amp;batchv1.Job{}
    r.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, job)


    return ctrl.Result{}, nil
}
</code></pre>
<p>How can I check within Reconcile the object kind? so I can retrieve the full object data calling <strong>r.Get</strong></p>

<p>By design, the event that triggered reconciliation is not passed to the reconciler so that you are forced to define and act on a state instead. This approach is referred to as <a href="http://venkateshabbarapu.blogspot.com/2013/03/edge-triggered-vs-level-triggered.html" rel="nofollow noreferrer">level-based, as opposed to edge-based</a>.</p>
<p>In your example you have two resources you are trying to keep track of. I would suggest either:</p>
<ol>
<li>Using ownerReferences or labels if these resources are related. That way you can get all related Datasets for a given Job (or vice versa) and reconcile things that way.</li>
<li>If the two resources are not related, create a separate controller for each resource.</li>
</ol>
<p>If you want to prevent reconciliation on certain events you can make use of predicates. From the event in the predicate function you can get the object type by <code>e.Object.(*core.Pod)</code> for example.</p>
