homepage: refactor and fix overrides not being applied

This commit is contained in:
yusing 2025-02-25 11:31:06 +08:00
parent 626d48d151
commit ac72f77a74
8 changed files with 75 additions and 67 deletions

View file

@ -86,8 +86,8 @@ func GetFavIcon(w http.ResponseWriter, req *http.Request) {
} }
var result *fetchResult var result *fetchResult
hp := r.HomepageConfig() hp := r.HomepageItem()
if !hp.IsEmpty() && hp.Icon != nil { if hp.Icon != nil {
if hp.Icon.IconSource == homepage.IconSourceRelative { if hp.Icon.IconSource == homepage.IconSourceRelative {
result = findIcon(r, req, hp.Icon.Value) result = findIcon(r, req, hp.Icon.Value)
} else { } else {

View file

@ -1,13 +1,15 @@
package homepage package homepage
import ( import (
"encoding/json"
config "github.com/yusing/go-proxy/internal/config/types"
"github.com/yusing/go-proxy/internal/utils" "github.com/yusing/go-proxy/internal/utils"
) )
type ( type (
//nolint:recvcheck Homepage map[string]Category
Categories map[string]Category Category []*Item
Category []*Item
ItemConfig struct { ItemConfig struct {
Show bool `json:"show"` Show bool `json:"show"`
@ -22,11 +24,8 @@ type (
Item struct { Item struct {
*ItemConfig *ItemConfig
Alias string `json:"alias"` // proxy alias Alias string
Provider string `json:"provider"` Provider string
URL string `json:"url"` // alias + domain
IsUnset bool `json:"-"`
} }
) )
@ -38,33 +37,34 @@ func init() {
}) })
} }
func NewItem(alias string) *Item { func (cfg *ItemConfig) GetOverride(alias string) *ItemConfig {
return &Item{ return overrideConfigInstance.GetOverride(alias, cfg)
ItemConfig: &ItemConfig{ }
Show: true,
}, func (item *Item) MarshalJSON() ([]byte, error) {
Alias: alias, godoxyCfg := config.GetInstance().Value()
IsUnset: true, // use first domain as base domain
domains := godoxyCfg.MatchDomains
var url *string
if len(domains) > 0 {
url = new(string)
*url = item.Alias + domains[0]
} }
return json.Marshal(map[string]any{
"show": item.Show,
"alias": item.Alias,
"provider": item.Provider,
"url": url,
"name": item.Name,
"icon": item.Icon,
"category": item.Category,
"description": item.Description,
"sort_order": item.SortOrder,
"widget_config": item.WidgetConfig,
})
} }
func NewHomePageConfig() Categories { func (c Homepage) Add(item *Item) {
return Categories(make(map[string]Category))
}
func (item *Item) IsEmpty() bool {
return item == nil || item.IsUnset || item.ItemConfig == nil
}
func (item *Item) ApplyOverride() *Item {
return overrideConfigInstance.ApplyOverride(item)
}
func (c *Categories) Clear() {
*c = make(Categories)
}
func (c Categories) Add(item *Item) {
if c[item.Category] == nil { if c[item.Category] == nil {
c[item.Category] = make(Category, 0) c[item.Category] = make(Category, 0)
} }

View file

@ -20,7 +20,7 @@ func TestOverrideItem(t *testing.T) {
Category: "App", Category: "App",
}, },
} }
override := &ItemConfig{ want := &ItemConfig{
Show: true, Show: true,
Name: "Bar", Name: "Bar",
Category: "Test", Category: "Test",
@ -30,7 +30,7 @@ func TestOverrideItem(t *testing.T) {
}, },
} }
overrides := GetOverrideConfig() overrides := GetOverrideConfig()
overrides.OverrideItem(a.Alias, override) overrides.OverrideItem(a.Alias, want)
overridden := a.ApplyOverride() got := a.GetOverride(a.Alias)
ExpectDeepEqual(t, overridden.ItemConfig, override) ExpectDeepEqual(t, got, want)
} }

View file

@ -64,16 +64,17 @@ func (c *OverrideConfig) OverrideItems(items map[string]*ItemConfig) {
} }
} }
func (c *OverrideConfig) ApplyOverride(item *Item) *Item { func (c *OverrideConfig) GetOverride(alias string, item *ItemConfig) *ItemConfig {
c.mu.RLock() c.mu.RLock()
defer c.mu.RUnlock() defer c.mu.RUnlock()
itemOverride, hasOverride := c.ItemOverrides[item.Alias] itemOverride, hasOverride := c.ItemOverrides[alias]
if hasOverride { if hasOverride {
item.ItemConfig = itemOverride return itemOverride
item.IsUnset = false
} }
if show, ok := c.ItemVisibility[item.Alias]; ok { if show, ok := c.ItemVisibility[alias]; ok {
item.Show = show clone := *item
clone.Show = show
return &clone
} }
return item return item
} }

View file

@ -225,7 +225,7 @@ func (r *ReveseProxyRoute) addToLoadBalancer(parent task.Parent) {
linked = l.(*ReveseProxyRoute) linked = l.(*ReveseProxyRoute)
lb = linked.loadBalancer lb = linked.loadBalancer
lb.UpdateConfigIfNeeded(cfg) lb.UpdateConfigIfNeeded(cfg)
if linked.Homepage.IsEmpty() && !r.Homepage.IsEmpty() { if linked.Homepage == nil {
linked.Homepage = r.Homepage linked.Homepage = r.Homepage
} }
} else { } else {

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/docker/docker/api/types/container"
"github.com/yusing/go-proxy/agent/pkg/agent" "github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/internal" "github.com/yusing/go-proxy/internal"
"github.com/yusing/go-proxy/internal/docker" "github.com/yusing/go-proxy/internal/docker"
@ -15,7 +16,6 @@ import (
"github.com/yusing/go-proxy/internal/utils/strutils" "github.com/yusing/go-proxy/internal/utils/strutils"
"github.com/yusing/go-proxy/internal/watcher/health" "github.com/yusing/go-proxy/internal/watcher/health"
dockertypes "github.com/docker/docker/api/types"
"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/gphttp/accesslog" "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
@ -41,7 +41,7 @@ type (
HealthCheck *health.HealthCheckConfig `json:"healthcheck,omitempty"` HealthCheck *health.HealthCheckConfig `json:"healthcheck,omitempty"`
LoadBalance *loadbalance.Config `json:"load_balance,omitempty"` LoadBalance *loadbalance.Config `json:"load_balance,omitempty"`
Middlewares map[string]docker.LabelMap `json:"middlewares,omitempty"` Middlewares map[string]docker.LabelMap `json:"middlewares,omitempty"`
Homepage *homepage.Item `json:"homepage,omitempty"` Homepage *homepage.ItemConfig `json:"homepage,omitempty"`
AccessLog *accesslog.Config `json:"access_log,omitempty"` AccessLog *accesslog.Config `json:"access_log,omitempty"`
Metadata `deserialize:"-"` Metadata `deserialize:"-"`
@ -190,8 +190,16 @@ func (r *Route) LoadBalanceConfig() *loadbalance.Config {
return r.LoadBalance return r.LoadBalance
} }
func (r *Route) HomepageConfig() *homepage.Item { func (r *Route) HomepageConfig() *homepage.ItemConfig {
return r.Homepage return r.Homepage.GetOverride(r.Alias)
}
func (r *Route) HomepageItem() *homepage.Item {
return &homepage.Item{
Alias: r.Alias,
Provider: r.Provider,
ItemConfig: r.HomepageConfig(),
}
} }
func (r *Route) ContainerInfo() *docker.Container { func (r *Route) ContainerInfo() *docker.Container {
@ -370,14 +378,12 @@ func (r *Route) FinalizeHomepageConfig() {
isDocker := r.Container != nil isDocker := r.Container != nil
if r.Homepage.IsEmpty() { if r.Homepage == nil {
r.Homepage = homepage.NewItem(r.Alias) r.Homepage = &homepage.ItemConfig{Show: true}
} }
r.Homepage = r.Homepage.GetOverride(r.Alias)
hp := r.Homepage hp := r.Homepage
hp.Alias = r.Alias
hp.Provider = r.Provider
hp = hp.ApplyOverride()
var key string var key string
if hp.Name == "" { if hp.Name == "" {
@ -424,7 +430,7 @@ func (r *Route) FinalizeHomepageConfig() {
} }
} }
func lowestPort(ports map[int]dockertypes.Port) (res int) { func lowestPort(ports map[int]container.Port) (res int) {
cmp := (uint16)(65535) cmp := (uint16)(65535)
for port, v := range ports { for port, v := range ports {
if v.PrivatePort < cmp { if v.PrivatePort < cmp {

View file

@ -64,33 +64,33 @@ func HomepageCategories() []string {
check := make(map[string]struct{}) check := make(map[string]struct{})
categories := make([]string, 0) categories := make([]string, 0)
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) { routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
homepage := r.HomepageConfig() item := r.HomepageConfig()
if homepage.IsEmpty() || homepage.Category == "" { if item == nil || item.Category == "" {
return return
} }
if _, ok := check[homepage.Category]; ok { if _, ok := check[item.Category]; ok {
return return
} }
check[homepage.Category] = struct{}{} check[item.Category] = struct{}{}
categories = append(categories, homepage.Category) categories = append(categories, item.Category)
}) })
return categories return categories
} }
func HomepageConfig(categoryFilter, providerFilter string) homepage.Categories { func HomepageConfig(categoryFilter, providerFilter string) homepage.Homepage {
hpCfg := homepage.NewHomePageConfig() hp := make(homepage.Homepage)
routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) { routes.GetHTTPRoutes().RangeAll(func(alias string, r route.HTTPRoute) {
item := r.HomepageConfig() if providerFilter != "" && r.ProviderName() != providerFilter {
if providerFilter != "" && item.Provider != providerFilter {
return return
} }
item := r.HomepageItem()
if categoryFilter != "" && item.Category != categoryFilter { if categoryFilter != "" && item.Category != categoryFilter {
return return
} }
hpCfg.Add(item) hp.Add(item)
}) })
return hpCfg return hp
} }
func RoutesByAlias(typeFilter ...route.RouteType) map[string]route.Route { func RoutesByAlias(typeFilter ...route.RouteType) map[string]route.Route {

View file

@ -29,7 +29,8 @@ type (
IdlewatcherConfig() *idlewatcher.Config IdlewatcherConfig() *idlewatcher.Config
HealthCheckConfig() *health.HealthCheckConfig HealthCheckConfig() *health.HealthCheckConfig
LoadBalanceConfig() *loadbalance.Config LoadBalanceConfig() *loadbalance.Config
HomepageConfig() *homepage.Item HomepageConfig() *homepage.ItemConfig
HomepageItem() *homepage.Item
ContainerInfo() *docker.Container ContainerInfo() *docker.Container
Agent() *agent.AgentConfig Agent() *agent.AgentConfig