Description
I've been working on a controller that interacts with another project's CRDs. All was going well until I encountered an error when trying to list owned objects using the reconciler's client with the code below:
if err := r.List(ctx, &ownedRules, client.MatchingField(ruleOwnerKey, req.Name)); err != nil {
log.Error(err, "unable to list owned rules")
return ctrl.Result{}, err
}
This caused the following error:
2019-10-23T12:41:43.568+0100 ERROR controller-runtime.controller Reconciler error {"controller": "servicelevelobjective", "request": "default/energy-fastly", "error": "cannot get cache for *v1.PrometheusRuleList, its element **v1.PrometheusRule is not a runtime.Object"}
Looking over the definition of the PrometheusRuleList
CRD I noted that the element type for the Items
field is *PrometheusRule
.
https://github.com/coreos/prometheus-operator/blob/v0.33.0/pkg/apis/monitoring/v1/types.go#L679
It appears the code in controller-runtime/pkg/cache/informer_cache.go
tries to determine whether the items can be cast to runtime.Object
and in the process assumes that the slice's elements are not pointers.
elemType := reflect.Indirect(reflect.ValueOf(itemsPtr)).Type().Elem()
cacheTypeValue := reflect.Zero(reflect.PtrTo(elemType))
I've fixed this locally by adding a check before converting the elemType to a Ptr which seems sufficient to fix the error in my use case.
elemType := reflect.Indirect(reflect.ValueOf(itemsPtr)).Type().Elem()
if elemType.Kind() != reflect.Ptr {
elemType = reflect.PtrTo(elemType)
}
cacheTypeValue := reflect.Zero(elemType)
I'm happy to put together a PR with this fix in it but wanted to raise the issue for discussion first in case there may be knock-on effects that I've not yet encountered as I haven't done extensive testing on my end yet.
Any thoughts from the owners on this one?