package debugger import ( "encoding/json" "net/http" "strings" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" clusterinformerv1 "open-cluster-management.io/api/client/cluster/informers/externalversions/cluster/v1" clusterinformerv1beta1 "open-cluster-management.io/api/client/cluster/informers/externalversions/cluster/v1beta1" clusterlisterv1 "open-cluster-management.io/api/client/cluster/listers/cluster/v1" clusterlisterv1beta1 "open-cluster-management.io/api/client/cluster/listers/cluster/v1beta1" "open-cluster-management.io/ocm/pkg/placement/controllers/scheduling" ) const DebugPath = "/debug/placements/" // Debugger provides a debug http endpoint for scheduler type Debugger struct { scheduler scheduling.Scheduler clusterLister clusterlisterv1.ManagedClusterLister placementLister clusterlisterv1beta1.PlacementLister } // DebugResult is the result returned by debugger type DebugResult struct { FilterResults []scheduling.FilterResult `json:"filteredPiplieResults,omitempty"` PrioritizeResults []scheduling.PrioritizerResult `json:"prioritizeResults,omitempty"` Error string `json:"error,omitempty"` } func NewDebugger( scheduler scheduling.Scheduler, placementInformer clusterinformerv1beta1.PlacementInformer, clusterInformer clusterinformerv1.ManagedClusterInformer) *Debugger { return &Debugger{ scheduler: scheduler, clusterLister: clusterInformer.Lister(), placementLister: placementInformer.Lister(), } } func (d *Debugger) Handler(w http.ResponseWriter, r *http.Request) { namespace, name, err := d.parsePath(r.URL.Path) if err != nil { d.reportErr(w, err) return } placement, err := d.placementLister.Placements(namespace).Get(name) if err != nil { d.reportErr(w, err) return } clusters, err := d.clusterLister.List(labels.Everything()) if err != nil { d.reportErr(w, err) return } scheduleResults, _ := d.scheduler.Schedule(r.Context(), placement, clusters) result := DebugResult{FilterResults: scheduleResults.FilterResults(), PrioritizeResults: scheduleResults.PrioritizerResults()} resultByte, _ := json.Marshal(result) _, _ = w.Write(resultByte) } func (d *Debugger) parsePath(path string) (string, string, error) { metaNamespaceKey := strings.TrimPrefix(path, DebugPath) return cache.SplitMetaNamespaceKey(metaNamespaceKey) } func (d *Debugger) reportErr(w http.ResponseWriter, err error) { result := &DebugResult{Error: err.Error()} resultByte, _ := json.Marshal(result) _, _ = w.Write(resultByte) }