refactor(api): restructured API for type safety, maintainability and docs generation

- These changes makes the API incombatible with previous versions
- Added new types for error handling, success responses, and health checks.
- Updated health check logic to utilize the new types for better clarity and structure.
- Refactored existing handlers to improve response consistency and error handling.
- Updated Makefile to include a new target for generating API types from Swagger.
- Updated "new agent" API to respond an encrypted cert pair
This commit is contained in:
yusing
2025-08-16 13:04:05 +08:00
parent fce9ce21c9
commit 35a3e3fef6
149 changed files with 13173 additions and 2173 deletions

View File

@@ -14,7 +14,7 @@ type AgentProvider struct {
}
func (p *AgentProvider) ShortName() string {
return p.AgentConfig.Name()
return p.AgentConfig.Name
}
func (p *AgentProvider) NewWatcher() watcher.Watcher {

View File

@@ -13,6 +13,7 @@ import (
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/serialization"
"github.com/yusing/go-proxy/internal/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
"github.com/yusing/go-proxy/internal/watcher"
)
@@ -78,7 +79,7 @@ func (p *DockerProvider) loadRoutesImpl() (route.Routes, gperr.Error) {
}
if container.IsHostNetworkMode {
err := container.UpdatePorts()
err := docker.UpdatePorts(container)
if err != nil {
errs.Add(gperr.PrependSubject(container.ContainerName, err))
continue
@@ -111,7 +112,7 @@ func (p *DockerProvider) loadRoutesImpl() (route.Routes, gperr.Error) {
// Returns a list of proxy entries for a container.
// Always non-nil.
func (p *DockerProvider) routesFromContainerLabels(container *docker.Container) (route.Routes, gperr.Error) {
func (p *DockerProvider) routesFromContainerLabels(container *types.Container) (route.Routes, gperr.Error) {
if !container.IsExplicit && p.IsExplicitOnly() {
return make(route.Routes, 0), nil
}
@@ -138,10 +139,10 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
continue
}
entryMap, ok := entryMapAny.(docker.LabelMap)
entryMap, ok := entryMapAny.(types.LabelMap)
if !ok {
// try to deserialize to map
entryMap = make(docker.LabelMap)
entryMap = make(types.LabelMap)
yamlStr, ok := entryMapAny.(string)
if !ok {
// should not happen

View File

@@ -10,11 +10,12 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/internal/docker"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route"
provider "github.com/yusing/go-proxy/internal/route/provider/types"
"github.com/yusing/go-proxy/internal/route/routes"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/types"
W "github.com/yusing/go-proxy/internal/watcher"
"github.com/yusing/go-proxy/internal/watcher/events"
)
@@ -45,7 +46,7 @@ const (
var ErrEmptyProviderName = errors.New("empty provider name")
var _ routes.Provider = (*Provider)(nil)
var _ types.RouteProvider = (*Provider)(nil)
func newProvider(t provider.Type) *Provider {
return &Provider{t: t}
@@ -76,7 +77,7 @@ func NewAgentProvider(cfg *agent.AgentConfig) *Provider {
p := newProvider(provider.ProviderTypeAgent)
agent := &AgentProvider{
AgentConfig: cfg,
docker: DockerProviderImpl(cfg.Name(), cfg.FakeDockerHost()),
docker: DockerProviderImpl(cfg.Name, cfg.FakeDockerHost()),
}
p.ProviderImpl = agent
p.watcher = p.NewWatcher()
@@ -145,7 +146,7 @@ func (p *Provider) NumRoutes() int {
return len(p.routes)
}
func (p *Provider) IterRoutes(yield func(string, routes.Route) bool) {
func (p *Provider) IterRoutes(yield func(string, types.Route) bool) {
routes := p.lockCloneRoutes()
for alias, r := range routes {
if !yield(alias, r.Impl()) {
@@ -154,7 +155,7 @@ func (p *Provider) IterRoutes(yield func(string, routes.Route) bool) {
}
}
func (p *Provider) FindService(project, service string) (routes.Route, bool) {
func (p *Provider) FindService(project, service string) (types.Route, bool) {
switch p.GetType() {
case provider.ProviderTypeDocker, provider.ProviderTypeAgent:
default:
@@ -166,17 +167,17 @@ func (p *Provider) FindService(project, service string) (routes.Route, bool) {
routes := p.lockCloneRoutes()
for _, r := range routes {
cont := r.ContainerInfo()
if cont.DockerComposeProject() != project {
if docker.DockerComposeProject(cont) != project {
continue
}
if cont.DockerComposeService() == service {
if docker.DockerComposeService(cont) == service {
return r.Impl(), true
}
}
return nil, false
}
func (p *Provider) GetRoute(alias string) (routes.Route, bool) {
func (p *Provider) GetRoute(alias string) (types.Route, bool) {
r, ok := p.lockGetRoute(alias)
if !ok {
return nil, false

View File

@@ -1,61 +1,12 @@
package provider
import (
R "github.com/yusing/go-proxy/internal/route"
provider "github.com/yusing/go-proxy/internal/route/provider/types"
route "github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/watcher/health"
"github.com/yusing/go-proxy/internal/types"
)
type (
RouteStats struct {
Total uint16 `json:"total"`
NumHealthy uint16 `json:"healthy"`
NumUnhealthy uint16 `json:"unhealthy"`
NumNapping uint16 `json:"napping"`
NumError uint16 `json:"error"`
NumUnknown uint16 `json:"unknown"`
}
ProviderStats struct {
Total uint16 `json:"total"`
RPs RouteStats `json:"reverse_proxies"`
Streams RouteStats `json:"streams"`
Type provider.Type `json:"type"`
}
)
func (stats *RouteStats) Add(r *R.Route) {
stats.Total++
mon := r.HealthMonitor()
if mon == nil {
stats.NumUnknown++
return
}
switch mon.Status() {
case health.StatusHealthy:
stats.NumHealthy++
case health.StatusUnhealthy:
stats.NumUnhealthy++
case health.StatusNapping:
stats.NumNapping++
case health.StatusError:
stats.NumError++
default:
stats.NumUnknown++
}
}
func (stats *RouteStats) AddOther(other RouteStats) {
stats.Total += other.Total
stats.NumHealthy += other.NumHealthy
stats.NumUnhealthy += other.NumUnhealthy
stats.NumNapping += other.NumNapping
stats.NumError += other.NumError
stats.NumUnknown += other.NumUnknown
}
func (p *Provider) Statistics() ProviderStats {
var rps, streams RouteStats
func (p *Provider) Statistics() types.ProviderStats {
var rps, streams types.RouteStats
for _, r := range p.routes {
switch r.Type() {
case route.RouteTypeHTTP:
@@ -64,7 +15,7 @@ func (p *Provider) Statistics() ProviderStats {
streams.Add(r)
}
}
return ProviderStats{
return types.ProviderStats{
Total: rps.Total + streams.Total,
RPs: rps,
Streams: streams,

View File

@@ -1,6 +1,6 @@
package provider
type Type string
type Type string // @name ProviderType
const (
ProviderTypeDocker Type = "docker"