From c1bf5017348f056b36978493ebead0081e6d3068 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Wed, 9 Feb 2022 11:37:09 +0800 Subject: [PATCH] update webapi --- cmd/gost/main.go | 1 + pkg/api/api.go | 36 +- pkg/api/doc.go | 2 +- pkg/api/swagger.yaml | 761 +++++++++++++++++++++++++++++++++++++++++++ pkg/config/config.go | 4 +- 5 files changed, 792 insertions(+), 12 deletions(-) create mode 100644 pkg/api/swagger.yaml diff --git a/cmd/gost/main.go b/cmd/gost/main.go index ce80558..2bc9c96 100644 --- a/cmd/gost/main.go +++ b/cmd/gost/main.go @@ -94,6 +94,7 @@ func main() { } if cfg.API != nil && cfg.API.Addr != "" { + api.Init(cfg.API) ln, err := net.Listen("tcp", cfg.API.Addr) if err != nil { log.Fatal(err) diff --git a/pkg/api/api.go b/pkg/api/api.go index 5e0a76d..e6aa793 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -1,36 +1,52 @@ package api import ( + "embed" "net" "net/http" "time" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" + "github.com/go-gost/gost/pkg/config" "github.com/go-gost/gost/pkg/logger" ) var ( apiServer = &http.Server{} + + //go:embed swagger.yaml + swaggerDoc embed.FS ) -func init() { +func Init(cfg *config.APIConfig) { gin.SetMode(gin.ReleaseMode) + if cfg == nil { + cfg = &config.APIConfig{} + } + r := gin.New() r.Use( cors.New((cors.Config{ AllowAllOrigins: true, - AllowMethods: []string{"GET", "POST", "PUT", "DELETE"}, + AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, AllowHeaders: []string{"*"}, })), - loggerHandler, gin.Recovery(), ) + if cfg.AccessLog { + r.Use(loggerHandler) + } - r.StaticFile("/swagger.yaml", "swagger.yaml") + router := r.Group("") + if cfg.PathPrefix != "" { + router = router.Group(cfg.PathPrefix) + } - config := r.Group("/config") + router.StaticFS("/docs", http.FS(swaggerDoc)) + + config := router.Group("/config") { config.GET("", getConfig) @@ -58,11 +74,6 @@ func init() { apiServer.Handler = r } -type Response struct { - Code int `json:"code,omitempty"` - Msg string `json:"msg,omitempty"` -} - func Run(ln net.Listener) error { return apiServer.Serve(ln) } @@ -84,3 +95,8 @@ func loggerHandler(ctx *gin.Context) { }).Infof("| %3d | %13v | %15s | %-7s %s", ctx.Writer.Status(), duration, ctx.ClientIP(), ctx.Request.Method, ctx.Request.RequestURI) } + +type Response struct { + Code int `json:"code,omitempty"` + Msg string `json:"msg,omitempty"` +} diff --git a/pkg/api/doc.go b/pkg/api/doc.go index 095da4f..fe45a6d 100644 --- a/pkg/api/doc.go +++ b/pkg/api/doc.go @@ -1,4 +1,4 @@ -// Documentation of GOST Web API. +// Documentation of Web API. // // Schemes: http // BasePath: / diff --git a/pkg/api/swagger.yaml b/pkg/api/swagger.yaml new file mode 100644 index 0000000..1a235fb --- /dev/null +++ b/pkg/api/swagger.yaml @@ -0,0 +1,761 @@ +basePath: / +consumes: +- application/json +definitions: + APIConfig: + properties: + accesslog: + type: boolean + x-go-name: AccessLog + addr: + type: string + x-go-name: Addr + pathPrefix: + type: string + x-go-name: PathPrefix + type: object + x-go-package: github.com/go-gost/gost/pkg/config + AuthConfig: + properties: + password: + type: string + x-go-name: Password + username: + type: string + x-go-name: Username + type: object + x-go-package: github.com/go-gost/gost/pkg/config + BypassConfig: + properties: + matchers: + items: + type: string + type: array + x-go-name: Matchers + name: + type: string + x-go-name: Name + reverse: + type: boolean + x-go-name: Reverse + type: object + x-go-package: github.com/go-gost/gost/pkg/config + ChainConfig: + properties: + hops: + items: + $ref: '#/definitions/HopConfig' + type: array + x-go-name: Hops + name: + type: string + x-go-name: Name + selector: + $ref: '#/definitions/SelectorConfig' + type: object + x-go-package: github.com/go-gost/gost/pkg/config + Config: + properties: + api: + $ref: '#/definitions/APIConfig' + bypasses: + items: + $ref: '#/definitions/BypassConfig' + type: array + x-go-name: Bypasses + chains: + items: + $ref: '#/definitions/ChainConfig' + type: array + x-go-name: Chains + hosts: + items: + $ref: '#/definitions/HostsConfig' + type: array + x-go-name: Hosts + log: + $ref: '#/definitions/LogConfig' + profiling: + $ref: '#/definitions/ProfilingConfig' + resolvers: + items: + $ref: '#/definitions/ResolverConfig' + type: array + x-go-name: Resolvers + services: + items: + $ref: '#/definitions/ServiceConfig' + type: array + x-go-name: Services + tls: + $ref: '#/definitions/TLSConfig' + type: object + x-go-package: github.com/go-gost/gost/pkg/config + ConnectorConfig: + properties: + auth: + $ref: '#/definitions/AuthConfig' + metadata: + additionalProperties: + type: object + type: object + x-go-name: Metadata + tls: + $ref: '#/definitions/TLSConfig' + type: + type: string + x-go-name: Type + type: object + x-go-package: github.com/go-gost/gost/pkg/config + DialerConfig: + properties: + auth: + $ref: '#/definitions/AuthConfig' + metadata: + additionalProperties: + type: object + type: object + x-go-name: Metadata + tls: + $ref: '#/definitions/TLSConfig' + type: + type: string + x-go-name: Type + type: object + x-go-package: github.com/go-gost/gost/pkg/config + Duration: + description: |- + A Duration represents the elapsed time between two instants + as an int64 nanosecond count. The representation limits the + largest representable duration to approximately 290 years. + format: int64 + type: integer + x-go-package: time + ForwarderConfig: + properties: + selector: + $ref: '#/definitions/SelectorConfig' + targets: + items: + type: string + type: array + x-go-name: Targets + type: object + x-go-package: github.com/go-gost/gost/pkg/config + HandlerConfig: + properties: + auths: + items: + $ref: '#/definitions/AuthConfig' + type: array + x-go-name: Auths + chain: + type: string + x-go-name: Chain + metadata: + additionalProperties: + type: object + type: object + x-go-name: Metadata + retries: + format: int64 + type: integer + x-go-name: Retries + tls: + $ref: '#/definitions/TLSConfig' + type: + type: string + x-go-name: Type + type: object + x-go-package: github.com/go-gost/gost/pkg/config + HopConfig: + properties: + bypass: + type: string + x-go-name: Bypass + hosts: + type: string + x-go-name: Hosts + name: + type: string + x-go-name: Name + nodes: + items: + $ref: '#/definitions/NodeConfig' + type: array + x-go-name: Nodes + resolver: + type: string + x-go-name: Resolver + selector: + $ref: '#/definitions/SelectorConfig' + type: object + x-go-package: github.com/go-gost/gost/pkg/config + HostMappingConfig: + properties: + aliases: + items: + type: string + type: array + x-go-name: Aliases + hostname: + type: string + x-go-name: Hostname + ip: + type: string + x-go-name: IP + type: object + x-go-package: github.com/go-gost/gost/pkg/config + HostsConfig: + properties: + mappings: + items: + $ref: '#/definitions/HostMappingConfig' + type: array + x-go-name: Mappings + name: + type: string + x-go-name: Name + type: object + x-go-package: github.com/go-gost/gost/pkg/config + ListenerConfig: + properties: + auths: + items: + $ref: '#/definitions/AuthConfig' + type: array + x-go-name: Auths + chain: + type: string + x-go-name: Chain + metadata: + additionalProperties: + type: object + type: object + x-go-name: Metadata + tls: + $ref: '#/definitions/TLSConfig' + type: + type: string + x-go-name: Type + type: object + x-go-package: github.com/go-gost/gost/pkg/config + LogConfig: + properties: + format: + type: string + x-go-name: Format + level: + type: string + x-go-name: Level + output: + type: string + x-go-name: Output + type: object + x-go-package: github.com/go-gost/gost/pkg/config + NameserverConfig: + properties: + addr: + type: string + x-go-name: Addr + chain: + type: string + x-go-name: Chain + clientIP: + type: string + x-go-name: ClientIP + hostname: + type: string + x-go-name: Hostname + prefer: + type: string + x-go-name: Prefer + timeout: + $ref: '#/definitions/Duration' + ttl: + $ref: '#/definitions/Duration' + type: object + x-go-package: github.com/go-gost/gost/pkg/config + NodeConfig: + properties: + addr: + type: string + x-go-name: Addr + bypass: + type: string + x-go-name: Bypass + connector: + $ref: '#/definitions/ConnectorConfig' + dialer: + $ref: '#/definitions/DialerConfig' + hosts: + type: string + x-go-name: Hosts + name: + type: string + x-go-name: Name + resolver: + type: string + x-go-name: Resolver + type: object + x-go-package: github.com/go-gost/gost/pkg/config + ProfilingConfig: + properties: + addr: + type: string + x-go-name: Addr + enabled: + type: boolean + x-go-name: Enabled + type: object + x-go-package: github.com/go-gost/gost/pkg/config + ResolverConfig: + properties: + name: + type: string + x-go-name: Name + nameservers: + items: + $ref: '#/definitions/NameserverConfig' + type: array + x-go-name: Nameservers + type: object + x-go-package: github.com/go-gost/gost/pkg/config + Response: + properties: + code: + format: int64 + type: integer + x-go-name: Code + msg: + type: string + x-go-name: Msg + type: object + x-go-package: github.com/go-gost/gost/pkg/api + SelectorConfig: + properties: + failTimeout: + $ref: '#/definitions/Duration' + maxFails: + format: int64 + type: integer + x-go-name: MaxFails + strategy: + type: string + x-go-name: Strategy + type: object + x-go-package: github.com/go-gost/gost/pkg/config + ServiceConfig: + properties: + addr: + type: string + x-go-name: Addr + bypass: + type: string + x-go-name: Bypass + forwarder: + $ref: '#/definitions/ForwarderConfig' + handler: + $ref: '#/definitions/HandlerConfig' + hosts: + type: string + x-go-name: Hosts + listener: + $ref: '#/definitions/ListenerConfig' + name: + type: string + x-go-name: Name + resolver: + type: string + x-go-name: Resolver + type: object + x-go-package: github.com/go-gost/gost/pkg/config + TLSConfig: + properties: + caFile: + type: string + x-go-name: CAFile + certFile: + type: string + x-go-name: CertFile + keyFile: + type: string + x-go-name: KeyFile + secure: + type: boolean + x-go-name: Secure + serverName: + type: string + x-go-name: ServerName + type: object + x-go-package: github.com/go-gost/gost/pkg/config +info: + title: Documentation of Web API. + version: 1.0.0 +paths: + /config: + get: + operationId: getConfigRequest + parameters: + - description: output format, one of yaml|json, default is json. + in: query + name: format + type: string + x-go-name: Format + responses: + "200": + $ref: '#/responses/getConfigResponse' + summary: Get current config. + tags: + - ConfigManagement + /config/bypasses: + post: + operationId: createBypassRequest + parameters: + - in: body + name: data + schema: + $ref: '#/definitions/BypassConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/createBypassResponse' + summary: create a new bypass, the name of bypass must be unique in bypass list. + tags: + - ConfigManagement + /config/bypasses/{bypass}: + delete: + operationId: deleteBypassRequest + parameters: + - in: path + name: bypass + required: true + type: string + x-go-name: Bypass + responses: + "200": + $ref: '#/responses/deleteBypassResponse' + summary: delete bypass by name. + tags: + - ConfigManagement + put: + operationId: updateBypassRequest + parameters: + - in: path + name: bypass + required: true + type: string + x-go-name: Bypass + - in: body + name: data + schema: + $ref: '#/definitions/BypassConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/updateBypassResponse' + summary: update bypass by name, the bypass must already exist. + tags: + - ConfigManagement + /config/chains: + post: + operationId: createChainRequest + parameters: + - in: body + name: data + schema: + $ref: '#/definitions/ChainConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/createChainResponse' + summary: create a new chain, the name of chain must be unique in chain list. + tags: + - ConfigManagement + /config/chains/{chain}: + delete: + operationId: deleteChainRequest + parameters: + - in: path + name: chain + required: true + type: string + x-go-name: Chain + responses: + "200": + $ref: '#/responses/deleteChainResponse' + summary: delete chain by name. + tags: + - ConfigManagement + put: + operationId: updateChainRequest + parameters: + - in: path + name: chain + required: true + type: string + x-go-name: Chain + - in: body + name: data + schema: + $ref: '#/definitions/ChainConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/updateChainResponse' + summary: update chain by name, the chain must already exist. + tags: + - ConfigManagement + /config/hosts: + post: + operationId: createHostsRequest + parameters: + - in: body + name: data + schema: + $ref: '#/definitions/HostsConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/createHostsResponse' + summary: create a new hosts, the name of the hosts must be unique in hosts list. + tags: + - ConfigManagement + /config/hosts/{hosts}: + delete: + operationId: deleteHostsRequest + parameters: + - in: path + name: hosts + required: true + type: string + x-go-name: Hosts + responses: + "200": + $ref: '#/responses/deleteHostsResponse' + summary: delete hosts by name. + tags: + - ConfigManagement + put: + operationId: updateHostsRequest + parameters: + - in: path + name: hosts + required: true + type: string + x-go-name: Hosts + - in: body + name: data + schema: + $ref: '#/definitions/HostsConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/updateHostsResponse' + summary: update hosts by name, the hosts must already exist. + tags: + - ConfigManagement + /config/resolvers: + post: + operationId: createResolverRequest + parameters: + - in: body + name: data + schema: + $ref: '#/definitions/ResolverConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/createResolverResponse' + summary: create a new resolver, the name of the resolver must be unique in resolver + list. + tags: + - ConfigManagement + /config/resolvers/{resolver}: + delete: + operationId: deleteResolverRequest + parameters: + - in: path + name: resolver + required: true + type: string + x-go-name: Resolver + responses: + "200": + $ref: '#/responses/deleteResolverResponse' + summary: delete resolver by name. + tags: + - ConfigManagement + put: + operationId: updateResolverRequest + parameters: + - in: path + name: resolver + required: true + type: string + x-go-name: Resolver + - in: body + name: data + schema: + $ref: '#/definitions/ResolverConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/updateResolverResponse' + summary: update resolver by name, the resolver must already exist. + tags: + - ConfigManagement + /config/services: + post: + operationId: createServiceRequest + parameters: + - in: body + name: data + schema: + $ref: '#/definitions/ServiceConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/createServiceResponse' + summary: create a new service, the name of the service must be unique in service + list. + tags: + - ConfigManagement + /config/services/{service}: + delete: + operationId: deleteServiceRequest + parameters: + - in: path + name: service + required: true + type: string + x-go-name: Service + responses: + "200": + $ref: '#/responses/deleteServiceResponse' + summary: delete service by name. + tags: + - ConfigManagement + put: + operationId: updateServiceRequest + parameters: + - in: path + name: service + required: true + type: string + x-go-name: Service + - in: body + name: data + schema: + $ref: '#/definitions/ServiceConfig' + x-go-name: Data + responses: + "200": + $ref: '#/responses/updateServiceResponse' + summary: update service by name, the service must already exist. + tags: + - ConfigManagement +produces: +- application/json +responses: + createBypassResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + createChainResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + createHostsResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + createResolverResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + createServiceResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + deleteBypassResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + deleteChainResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + deleteHostsResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + deleteResolverResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + deleteServiceResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + getConfigResponse: + description: successful operation. + headers: + Config: {} + schema: + $ref: '#/definitions/Config' + updateBypassResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + updateChainResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + updateHostsResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + updateResolverResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' + updateServiceResponse: + description: successful operation. + headers: + Data: {} + schema: + $ref: '#/definitions/Response' +schemes: +- http +securityDefinitions: + api_key: null +swagger: "2.0" diff --git a/pkg/config/config.go b/pkg/config/config.go index db7ae3e..2e00cc3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -54,7 +54,9 @@ type ProfilingConfig struct { } type APIConfig struct { - Addr string `json:"addr"` + Addr string `json:"addr"` + PathPrefix string `yaml:"pathPrefix,omitempty" json:"pathPrefix,omitempty"` + AccessLog bool `yaml:"accesslog,omitempty" json:"accesslog,omitemtpy"` } type TLSConfig struct {