diff --git a/pkg/bootstrap/server.go b/pkg/bootstrap/server.go index 9ac3851df..dce553247 100644 --- a/pkg/bootstrap/server.go +++ b/pkg/bootstrap/server.go @@ -398,6 +398,7 @@ func (s *Server) initHttpServer() error { } s.xdsServer.AddDebugHandlers(s.httpMux, nil, true, nil) s.httpMux.HandleFunc("/ready", s.readyHandler) + s.httpMux.HandleFunc("/registry/watcherStatus", s.registryWatcherStatusHandler) return nil } @@ -413,6 +414,43 @@ func (s *Server) readyHandler(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) } +func (s *Server) registryWatcherStatusHandler(w http.ResponseWriter, _ *http.Request) { + ingressTranslation, ok := s.environment.IngressStore.(*translation.IngressTranslation) + if !ok { + http.Error(w, "IngressStore not found", http.StatusNotFound) + return + } + + ingressConfig := ingressTranslation.GetIngressConfig() + if ingressConfig == nil { + http.Error(w, "IngressConfig not found", http.StatusNotFound) + return + } + + registryReconciler := ingressConfig.RegistryReconciler + if registryReconciler == nil { + http.Error(w, "RegistryReconciler not found", http.StatusNotFound) + return + } + + watcherStatusList := registryReconciler.GetRegistryWatcherStatusList() + writeJSON(w, watcherStatusList) +} + +func writeJSON(w http.ResponseWriter, obj interface{}) { + w.Header().Set("Content-Type", "application/json") + b, err := config.ToJSON(obj) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + _, _ = w.Write([]byte(err.Error())) + return + } + _, err = w.Write(b) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } +} + // cachesSynced checks whether caches have been synced. func (s *Server) cachesSynced() bool { return s.configController.HasSynced() diff --git a/pkg/ingress/translation/translation.go b/pkg/ingress/translation/translation.go index 457626735..2683006e4 100644 --- a/pkg/ingress/translation/translation.go +++ b/pkg/ingress/translation/translation.go @@ -73,6 +73,10 @@ func (m *IngressTranslation) InitializeCluster(ingressController common.IngressC return nil } +func (m *IngressTranslation) GetIngressConfig() *ingressconfig.IngressConfig { + return m.ingressConfig +} + func (m *IngressTranslation) RegisterEventHandler(kind config.GroupVersionKind, f model.EventHandler) { m.ingressConfig.RegisterEventHandler(kind, f) if m.kingressConfig != nil { diff --git a/registry/direct/watcher.go b/registry/direct/watcher.go index ed3e3f9a9..f4aa2b27a 100644 --- a/registry/direct/watcher.go +++ b/registry/direct/watcher.go @@ -162,3 +162,7 @@ func (w *watcher) generateServiceEntry(host string) *v1alpha3.ServiceEntry { } return se } + +func (w *watcher) GetRegistryType() string { + return w.RegistryConfig.Type +} diff --git a/registry/reconcile/reconcile.go b/registry/reconcile/reconcile.go index 34e8e3964..88e778311 100644 --- a/registry/reconcile/reconcile.go +++ b/registry/reconcile/reconcile.go @@ -278,3 +278,25 @@ func (r *Reconciler) getAuthOption(registry *apiv1.RegistryConfig) (AuthOption, return authOption, nil } + +type RegistryWatcherStatus struct { + Name string `json:"name"` + Type string `json:"type"` + Healthy bool `json:"healthy"` + Ready bool `json:"ready"` +} + +func (r *Reconciler) GetRegistryWatcherStatusList() []RegistryWatcherStatus { + var registryStatusList []RegistryWatcherStatus + for key, watcher := range r.watchers { + _, name := path.Split(key) + registryStatus := RegistryWatcherStatus{ + Name: name, + Type: watcher.GetRegistryType(), + Healthy: watcher.IsHealthy(), + Ready: watcher.IsReady(), + } + registryStatusList = append(registryStatusList, registryStatus) + } + return registryStatusList +} diff --git a/registry/watcher.go b/registry/watcher.go index 129ec0ec9..f43183b9d 100644 --- a/registry/watcher.go +++ b/registry/watcher.go @@ -49,6 +49,7 @@ type Watcher interface { Run() Stop() IsHealthy() bool + IsReady() bool GetRegistryType() string AppendServiceUpdateHandler(f func()) ReadyHandler(f func(bool)) @@ -57,17 +58,22 @@ type Watcher interface { type BaseWatcher struct { UpdateService ServiceUpdateHandler Ready ReadyHandler + ReadyStatus bool } func (w *BaseWatcher) Run() {} func (w *BaseWatcher) Stop() {} func (w *BaseWatcher) IsHealthy() bool { return true } +func (w *BaseWatcher) IsReady() bool { return w.ReadyStatus } func (w *BaseWatcher) GetRegistryType() string { return "" } func (w *BaseWatcher) AppendServiceUpdateHandler(f func()) { w.UpdateService = f } -func (w *BaseWatcher) ReadyHandler(f func(bool)) { - w.Ready = f +func (w *BaseWatcher) ReadyHandler(f func(isReady bool)) { + w.Ready = func(isReady bool) { + w.ReadyStatus = isReady + f(isReady) + } } type ServiceUpdateHandler func() diff --git a/registry/zookeeper/watcher.go b/registry/zookeeper/watcher.go index c9921cdf4..6f8f69bbb 100644 --- a/registry/zookeeper/watcher.go +++ b/registry/zookeeper/watcher.go @@ -678,7 +678,7 @@ func (w *watcher) Run() { select { case <-ticker.C: var needNewFetch bool - if w.IsReady() { + if w.watcherReady() { w.Ready(true) needNewFetch = true } @@ -727,7 +727,7 @@ func (w *watcher) GetRegistryType() string { return w.RegistryType.String() } -func (w *watcher) IsReady() bool { +func (w *watcher) watcherReady() bool { if w.serviceRemaind == nil { return true }