mirror of
https://github.com/yusing/godoxy.git
synced 2025-07-26 13:44:03 +02:00
api: added some endpoints for dashboard filter to work
This commit is contained in:
parent
bcc7faa8e5
commit
68771ce399
13 changed files with 82 additions and 34 deletions
|
@ -18,7 +18,7 @@ import (
|
||||||
E "github.com/yusing/go-proxy/internal/error"
|
E "github.com/yusing/go-proxy/internal/error"
|
||||||
"github.com/yusing/go-proxy/internal/logging"
|
"github.com/yusing/go-proxy/internal/logging"
|
||||||
"github.com/yusing/go-proxy/internal/net/http/middleware"
|
"github.com/yusing/go-proxy/internal/net/http/middleware"
|
||||||
"github.com/yusing/go-proxy/internal/route/routes"
|
"github.com/yusing/go-proxy/internal/route/routes/routequery"
|
||||||
"github.com/yusing/go-proxy/internal/task"
|
"github.com/yusing/go-proxy/internal/task"
|
||||||
"github.com/yusing/go-proxy/pkg"
|
"github.com/yusing/go-proxy/pkg"
|
||||||
)
|
)
|
||||||
|
@ -104,7 +104,7 @@ func main() {
|
||||||
switch args.Command {
|
switch args.Command {
|
||||||
case common.CommandListRoutes:
|
case common.CommandListRoutes:
|
||||||
cfg.StartProxyProviders()
|
cfg.StartProxyProviders()
|
||||||
printJSON(routes.RoutesByAlias())
|
printJSON(routequery.RoutesByAlias())
|
||||||
return
|
return
|
||||||
case common.CommandListConfigs:
|
case common.CommandListConfigs:
|
||||||
printJSON(cfg.Value())
|
printJSON(cfg.Value())
|
||||||
|
@ -113,7 +113,7 @@ func main() {
|
||||||
printJSON(cfg.DumpEntries())
|
printJSON(cfg.DumpEntries())
|
||||||
return
|
return
|
||||||
case common.CommandDebugListProviders:
|
case common.CommandDebugListProviders:
|
||||||
printJSON(cfg.DumpProviders())
|
printJSON(cfg.DumpRouteProviders())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,11 @@ import (
|
||||||
"github.com/coder/websocket/wsjson"
|
"github.com/coder/websocket/wsjson"
|
||||||
U "github.com/yusing/go-proxy/internal/api/v1/utils"
|
U "github.com/yusing/go-proxy/internal/api/v1/utils"
|
||||||
config "github.com/yusing/go-proxy/internal/config/types"
|
config "github.com/yusing/go-proxy/internal/config/types"
|
||||||
"github.com/yusing/go-proxy/internal/route/routes"
|
"github.com/yusing/go-proxy/internal/route/routes/routequery"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HealthWS(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
|
func HealthWS(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
|
||||||
U.PeriodicWS(cfg, w, r, 1*time.Second, func(conn *websocket.Conn) error {
|
U.PeriodicWS(cfg, w, r, 1*time.Second, func(conn *websocket.Conn) error {
|
||||||
return wsjson.Write(r.Context(), conn, routes.HealthMap())
|
return wsjson.Write(r.Context(), conn, routequery.HealthMap())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,23 @@ import (
|
||||||
"github.com/yusing/go-proxy/internal/common"
|
"github.com/yusing/go-proxy/internal/common"
|
||||||
config "github.com/yusing/go-proxy/internal/config/types"
|
config "github.com/yusing/go-proxy/internal/config/types"
|
||||||
"github.com/yusing/go-proxy/internal/net/http/middleware"
|
"github.com/yusing/go-proxy/internal/net/http/middleware"
|
||||||
"github.com/yusing/go-proxy/internal/route/routes"
|
"github.com/yusing/go-proxy/internal/route/routes/routequery"
|
||||||
route "github.com/yusing/go-proxy/internal/route/types"
|
route "github.com/yusing/go-proxy/internal/route/types"
|
||||||
"github.com/yusing/go-proxy/internal/task"
|
"github.com/yusing/go-proxy/internal/task"
|
||||||
"github.com/yusing/go-proxy/internal/utils"
|
"github.com/yusing/go-proxy/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ListRoute = "route"
|
ListRoute = "route"
|
||||||
ListRoutes = "routes"
|
ListRoutes = "routes"
|
||||||
ListFiles = "files"
|
ListFiles = "files"
|
||||||
ListMiddlewares = "middlewares"
|
ListMiddlewares = "middlewares"
|
||||||
ListMiddlewareTraces = "middleware_trace"
|
ListMiddlewareTraces = "middleware_trace"
|
||||||
ListMatchDomains = "match_domains"
|
ListMatchDomains = "match_domains"
|
||||||
ListHomepageConfig = "homepage_config"
|
ListHomepageConfig = "homepage_config"
|
||||||
ListTasks = "tasks"
|
ListRouteProviders = "route_providers"
|
||||||
|
ListHomepageCategories = "homepage_categories"
|
||||||
|
ListTasks = "tasks"
|
||||||
)
|
)
|
||||||
|
|
||||||
func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
|
func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -41,7 +43,7 @@ func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
|
||||||
U.RespondJSON(w, r, route)
|
U.RespondJSON(w, r, route)
|
||||||
}
|
}
|
||||||
case ListRoutes:
|
case ListRoutes:
|
||||||
U.RespondJSON(w, r, routes.RoutesByAlias(route.RouteType(r.FormValue("type"))))
|
U.RespondJSON(w, r, routequery.RoutesByAlias(route.RouteType(r.FormValue("type"))))
|
||||||
case ListFiles:
|
case ListFiles:
|
||||||
listFiles(w, r)
|
listFiles(w, r)
|
||||||
case ListMiddlewares:
|
case ListMiddlewares:
|
||||||
|
@ -51,7 +53,11 @@ func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
|
||||||
case ListMatchDomains:
|
case ListMatchDomains:
|
||||||
U.RespondJSON(w, r, cfg.Value().MatchDomains)
|
U.RespondJSON(w, r, cfg.Value().MatchDomains)
|
||||||
case ListHomepageConfig:
|
case ListHomepageConfig:
|
||||||
U.RespondJSON(w, r, routes.HomepageConfig(cfg.Value().Homepage.UseDefaultCategories))
|
U.RespondJSON(w, r, routequery.HomepageConfig(cfg.Value().Homepage.UseDefaultCategories, r.FormValue("category"), r.FormValue("provider")))
|
||||||
|
case ListRouteProviders:
|
||||||
|
U.RespondJSON(w, r, cfg.RouteProviderList())
|
||||||
|
case ListHomepageCategories:
|
||||||
|
U.RespondJSON(w, r, routequery.HomepageCategories())
|
||||||
case ListTasks:
|
case ListTasks:
|
||||||
U.RespondJSON(w, r, task.DebugTaskList())
|
U.RespondJSON(w, r, task.DebugTaskList())
|
||||||
default:
|
default:
|
||||||
|
@ -63,9 +69,9 @@ func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
|
||||||
// otherwise, return a single Route with alias which or nil if not found.
|
// otherwise, return a single Route with alias which or nil if not found.
|
||||||
func listRoute(which string) any {
|
func listRoute(which string) any {
|
||||||
if which == "" || which == "all" {
|
if which == "" || which == "all" {
|
||||||
return routes.RoutesByAlias()
|
return routequery.RoutesByAlias()
|
||||||
}
|
}
|
||||||
routes := routes.RoutesByAlias()
|
routes := routequery.RoutesByAlias()
|
||||||
route, ok := routes[which]
|
route, ok := routes[which]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -16,7 +16,7 @@ func (cfg *Config) DumpEntries() map[string]*types.RawEntry {
|
||||||
return entries
|
return entries
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *Config) DumpProviders() map[string]*provider.Provider {
|
func (cfg *Config) DumpRouteProviders() map[string]*provider.Provider {
|
||||||
entries := make(map[string]*provider.Provider)
|
entries := make(map[string]*provider.Provider)
|
||||||
cfg.providers.RangeAll(func(_ string, p *provider.Provider) {
|
cfg.providers.RangeAll(func(_ string, p *provider.Provider) {
|
||||||
entries[p.ShortName()] = p
|
entries[p.ShortName()] = p
|
||||||
|
@ -24,6 +24,14 @@ func (cfg *Config) DumpProviders() map[string]*provider.Provider {
|
||||||
return entries
|
return entries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) RouteProviderList() []string {
|
||||||
|
var list []string
|
||||||
|
cfg.providers.RangeAll(func(_ string, p *provider.Provider) {
|
||||||
|
list = append(list, p.ShortName())
|
||||||
|
})
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
func (cfg *Config) Statistics() map[string]any {
|
func (cfg *Config) Statistics() map[string]any {
|
||||||
var rps, streams provider.RouteStats
|
var rps, streams provider.RouteStats
|
||||||
var total uint16
|
var total uint16
|
||||||
|
|
|
@ -33,6 +33,7 @@ type (
|
||||||
Value() *Config
|
Value() *Config
|
||||||
Reload() E.Error
|
Reload() E.Error
|
||||||
Statistics() map[string]any
|
Statistics() map[string]any
|
||||||
|
RouteProviderList() []string
|
||||||
Context() context.Context
|
Context() context.Context
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,7 +33,6 @@ var PredefinedCategories = map[string]string{
|
||||||
"changedetection": "Monitoring",
|
"changedetection": "Monitoring",
|
||||||
"influxdb": "Monitoring",
|
"influxdb": "Monitoring",
|
||||||
"influx": "Monitoring",
|
"influx": "Monitoring",
|
||||||
"dozzle": "Monitoring",
|
|
||||||
|
|
||||||
"adguardhome": "Networking",
|
"adguardhome": "Networking",
|
||||||
"adgh": "Networking",
|
"adgh": "Networking",
|
||||||
|
@ -47,6 +46,8 @@ var PredefinedCategories = map[string]string{
|
||||||
"dockge": "Container Management",
|
"dockge": "Container Management",
|
||||||
"portainer-ce": "Container Management",
|
"portainer-ce": "Container Management",
|
||||||
"portainer-be": "Container Management",
|
"portainer-be": "Container Management",
|
||||||
|
"logs": "Container Management",
|
||||||
|
"dozzle": "Container Management",
|
||||||
|
|
||||||
"rss": "RSS",
|
"rss": "RSS",
|
||||||
"rsshub": "RSS",
|
"rsshub": "RSS",
|
||||||
|
@ -57,6 +58,7 @@ var PredefinedCategories = map[string]string{
|
||||||
"paperless": "Documents",
|
"paperless": "Documents",
|
||||||
"paperless-ngx": "Documents",
|
"paperless-ngx": "Documents",
|
||||||
"s-pdf": "Documents",
|
"s-pdf": "Documents",
|
||||||
|
"stirling-pdf": "Documents",
|
||||||
|
|
||||||
"minio": "Storage",
|
"minio": "Storage",
|
||||||
"filebrowser": "Storage",
|
"filebrowser": "Storage",
|
||||||
|
|
|
@ -17,6 +17,7 @@ type (
|
||||||
Alias string `json:"alias"` // proxy alias
|
Alias string `json:"alias"` // proxy alias
|
||||||
SourceType string `json:"source_type"`
|
SourceType string `json:"source_type"`
|
||||||
AltURL string `json:"alt_url"` // original proxy target
|
AltURL string `json:"alt_url"` // original proxy target
|
||||||
|
Provider string `json:"provider"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ func (p *DockerProvider) loadRoutesImpl() (route.Routes, E.Error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
routes, err = route.FromEntries(entries)
|
routes, err = route.FromEntries(p.ShortName(), entries)
|
||||||
errs.Add(err)
|
errs.Add(err)
|
||||||
|
|
||||||
return routes, errs.Error()
|
return routes, errs.Error()
|
||||||
|
|
|
@ -32,16 +32,16 @@ func FileProviderImpl(filename string) (ProviderImpl, error) {
|
||||||
return impl, nil
|
return impl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validate(data []byte) (route.Routes, E.Error) {
|
func validate(provider string, data []byte) (route.Routes, E.Error) {
|
||||||
entries, err := utils.DeserializeYAMLMap[*route.RawEntry](data)
|
entries, err := utils.DeserializeYAMLMap[*route.RawEntry](data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return route.NewRoutes(), err
|
return route.NewRoutes(), err
|
||||||
}
|
}
|
||||||
return route.FromEntries(entries)
|
return route.FromEntries(provider, entries)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Validate(data []byte) (err E.Error) {
|
func Validate(data []byte) (err E.Error) {
|
||||||
_, err = validate(data)
|
_, err = validate("", data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ func (p *FileProvider) loadRoutesImpl() (route.Routes, E.Error) {
|
||||||
return routes, E.From(err)
|
return routes, E.From(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return validate(data)
|
return validate(p.ShortName(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *FileProvider) NewWatcher() W.Watcher {
|
func (p *FileProvider) NewWatcher() W.Watcher {
|
||||||
|
|
|
@ -12,6 +12,6 @@ import (
|
||||||
var testAllFieldsYAML []byte
|
var testAllFieldsYAML []byte
|
||||||
|
|
||||||
func TestFile(t *testing.T) {
|
func TestFile(t *testing.T) {
|
||||||
_, err := validate(testAllFieldsYAML)
|
_, err := validate("", testAllFieldsYAML)
|
||||||
ExpectNoError(t, err)
|
ExpectNoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ func NewRoute(raw *RawEntry) (*Route, E.Error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromEntries(entries RawEntries) (Routes, E.Error) {
|
func FromEntries(provider string, entries RawEntries) (Routes, E.Error) {
|
||||||
b := E.NewBuilder("errors in routes")
|
b := E.NewBuilder("errors in routes")
|
||||||
|
|
||||||
routes := NewRoutes()
|
routes := NewRoutes()
|
||||||
|
@ -85,6 +85,7 @@ func FromEntries(entries RawEntries) (Routes, E.Error) {
|
||||||
en = new(RawEntry)
|
en = new(RawEntry)
|
||||||
}
|
}
|
||||||
en.Alias = alias
|
en.Alias = alias
|
||||||
|
en.Provider = provider
|
||||||
if strings.HasPrefix(alias, "x-") { // x properties
|
if strings.HasPrefix(alias, "x-") { // x properties
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package routes
|
package routequery
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/yusing/go-proxy/internal/homepage"
|
"github.com/yusing/go-proxy/internal/homepage"
|
||||||
"github.com/yusing/go-proxy/internal/route/entry"
|
"github.com/yusing/go-proxy/internal/route/entry"
|
||||||
provider "github.com/yusing/go-proxy/internal/route/provider/types"
|
provider "github.com/yusing/go-proxy/internal/route/provider/types"
|
||||||
|
"github.com/yusing/go-proxy/internal/route/routes"
|
||||||
route "github.com/yusing/go-proxy/internal/route/types"
|
route "github.com/yusing/go-proxy/internal/route/types"
|
||||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||||
)
|
)
|
||||||
|
@ -29,18 +30,36 @@ func getHealthInfo(r route.Route) map[string]string {
|
||||||
|
|
||||||
func HealthMap() map[string]map[string]string {
|
func HealthMap() map[string]map[string]string {
|
||||||
healthMap := make(map[string]map[string]string)
|
healthMap := make(map[string]map[string]string)
|
||||||
httpRoutes.RangeAll(func(alias string, r route.HTTPRoute) {
|
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
|
||||||
healthMap[alias] = getHealthInfo(r)
|
healthMap[alias] = getHealthInfo(r)
|
||||||
})
|
})
|
||||||
streamRoutes.RangeAll(func(alias string, r route.StreamRoute) {
|
routes.GetStreamRoutes().RangeAll(func(alias string, r route.StreamRoute) {
|
||||||
healthMap[alias] = getHealthInfo(r)
|
healthMap[alias] = getHealthInfo(r)
|
||||||
})
|
})
|
||||||
return healthMap
|
return healthMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func HomepageConfig(useDefaultCategories bool) homepage.Config {
|
func HomepageCategories() []string {
|
||||||
|
check := make(map[string]struct{})
|
||||||
|
categories := make([]string, 0)
|
||||||
|
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
|
||||||
|
en := r.RawEntry()
|
||||||
|
if en.Homepage == nil || en.Homepage.Category == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := check[en.Homepage.Category]; ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
check[en.Homepage.Category] = struct{}{}
|
||||||
|
categories = append(categories, en.Homepage.Category)
|
||||||
|
})
|
||||||
|
return categories
|
||||||
|
}
|
||||||
|
|
||||||
|
func HomepageConfig(useDefaultCategories bool, categoryFilter, providerFilter string) homepage.Config {
|
||||||
hpCfg := homepage.NewHomePageConfig()
|
hpCfg := homepage.NewHomePageConfig()
|
||||||
GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
|
|
||||||
|
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
|
||||||
en := r.RawEntry()
|
en := r.RawEntry()
|
||||||
item := en.Homepage
|
item := en.Homepage
|
||||||
if item == nil {
|
if item == nil {
|
||||||
|
@ -57,6 +76,11 @@ func HomepageConfig(useDefaultCategories bool) homepage.Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
item.Alias = alias
|
item.Alias = alias
|
||||||
|
item.Provider = r.RawEntry().Provider
|
||||||
|
|
||||||
|
if providerFilter != "" && item.Provider != providerFilter {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if item.Name == "" {
|
if item.Name == "" {
|
||||||
item.Name = strutils.Title(
|
item.Name = strutils.Title(
|
||||||
|
@ -81,6 +105,10 @@ func HomepageConfig(useDefaultCategories bool) homepage.Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if categoryFilter != "" && item.Category != categoryFilter {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case entry.IsDocker(r):
|
case entry.IsDocker(r):
|
||||||
if item.Category == "" {
|
if item.Category == "" {
|
||||||
|
@ -113,11 +141,11 @@ func RoutesByAlias(typeFilter ...route.RouteType) map[string]route.Route {
|
||||||
for _, t := range typeFilter {
|
for _, t := range typeFilter {
|
||||||
switch t {
|
switch t {
|
||||||
case route.RouteTypeReverseProxy:
|
case route.RouteTypeReverseProxy:
|
||||||
GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
|
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
|
||||||
rts[alias] = r
|
rts[alias] = r
|
||||||
})
|
})
|
||||||
case route.RouteTypeStream:
|
case route.RouteTypeStream:
|
||||||
GetStreamRoutes().RangeAll(func(alias string, r route.StreamRoute) {
|
routes.GetStreamRoutes().RangeAll(func(alias string, r route.StreamRoute) {
|
||||||
rts[alias] = r
|
rts[alias] = r
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -40,6 +40,7 @@ type (
|
||||||
|
|
||||||
/* Docker only */
|
/* Docker only */
|
||||||
Container *docker.Container `json:"container,omitempty"`
|
Container *docker.Container `json:"container,omitempty"`
|
||||||
|
Provider string `json:"provider,omitempty"`
|
||||||
|
|
||||||
finalized bool
|
finalized bool
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue