Skip to content

Commit

Permalink
feat: update to go1.24 & support listening https (#1002)
Browse files Browse the repository at this point in the history
* feat: support listening https

* refactor

* modernize

* support snake case in config

* more precise control of config fields

* update goreleaser config

* remove kubeyaml

* fix: expose agent_secret

* chore
  • Loading branch information
uubulb authored Feb 28, 2025
1 parent e770398 commit 1d2f8d2
Show file tree
Hide file tree
Showing 28 changed files with 318 additions and 172 deletions.
8 changes: 8 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ builds:
flags:
- -trimpath
- -buildvcs=false
tags:
- go_json
goos:
- linux
goarch:
Expand All @@ -31,6 +33,8 @@ builds:
flags:
- -trimpath
- -buildvcs=false
tags:
- go_json
goos:
- linux
goarch:
Expand All @@ -48,6 +52,8 @@ builds:
flags:
- -trimpath
- -buildvcs=false
tags:
- go_json
goos:
- linux
goarch:
Expand All @@ -65,6 +71,8 @@ builds:
flags:
- -trimpath
- -buildvcs=false
tags:
- go_json
goos:
- windows
goarch:
Expand Down
8 changes: 4 additions & 4 deletions cmd/dashboard/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,10 @@ type pHandlerFunc[S ~[]E, E any] func(c *gin.Context) (*model.Value[S], error)
// gorm errors here instead
type gormError struct {
msg string
a []interface{}
a []any
}

func newGormError(format string, args ...interface{}) error {
func newGormError(format string, args ...any) error {
return &gormError{
msg: format,
a: args,
Expand All @@ -191,10 +191,10 @@ func (ge *gormError) Error() string {

type wsError struct {
msg string
a []interface{}
a []any
}

func newWsError(format string, args ...interface{}) error {
func newWsError(format string, args ...any) error {
return &wsError{
msg: format,
a: args,
Expand Down
4 changes: 2 additions & 2 deletions cmd/dashboard/controller/fm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"time"

"github.com/gin-gonic/gin"
"github.com/goccy/go-json"
"github.com/gorilla/websocket"
"github.com/hashicorp/go-uuid"

"github.com/nezhahq/nezha/model"
"github.com/nezhahq/nezha/pkg/utils"
"github.com/nezhahq/nezha/pkg/websocketx"
"github.com/nezhahq/nezha/proto"
"github.com/nezhahq/nezha/service/rpc"
Expand Down Expand Up @@ -48,7 +48,7 @@ func createFM(c *gin.Context) (*model.CreateFMResponse, error) {

rpc.NezhaHandlerSingleton.CreateStream(streamId)

fmData, _ := utils.Json.Marshal(&model.TaskFM{
fmData, _ := json.Marshal(&model.TaskFM{
StreamID: streamId,
})
if err := server.TaskStream.Send(&proto.Task{
Expand Down
18 changes: 9 additions & 9 deletions cmd/dashboard/controller/jwt.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package controller

import (
"encoding/json"
"net/http"
"time"

jwt "github.com/appleboy/gin-jwt/v2"
"github.com/gin-gonic/gin"
"github.com/goccy/go-json"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"

Expand Down Expand Up @@ -48,8 +48,8 @@ func initParams() *jwt.GinJWTMiddleware {
}
}

func payloadFunc() func(data interface{}) jwt.MapClaims {
return func(data interface{}) jwt.MapClaims {
func payloadFunc() func(data any) jwt.MapClaims {
return func(data any) jwt.MapClaims {
if v, ok := data.(string); ok {
return jwt.MapClaims{
model.CtxKeyAuthorizedUser: v,
Expand All @@ -59,8 +59,8 @@ func payloadFunc() func(data interface{}) jwt.MapClaims {
}
}

func identityHandler() func(c *gin.Context) interface{} {
return func(c *gin.Context) interface{} {
func identityHandler() func(c *gin.Context) any {
return func(c *gin.Context) any {
claims := jwt.ExtractClaims(c)
userId := claims[model.CtxKeyAuthorizedUser].(string)
var user model.User
Expand All @@ -80,8 +80,8 @@ func identityHandler() func(c *gin.Context) interface{} {
// @Produce json
// @Success 200 {object} model.CommonResponse[model.LoginResponse]
// @Router /login [post]
func authenticator() func(c *gin.Context) (interface{}, error) {
return func(c *gin.Context) (interface{}, error) {
func authenticator() func(c *gin.Context) (any, error) {
return func(c *gin.Context) (any, error) {
var loginVals model.LoginRequest
if err := c.ShouldBind(&loginVals); err != nil {
return "", jwt.ErrMissingLoginValues
Expand Down Expand Up @@ -113,8 +113,8 @@ func authenticator() func(c *gin.Context) (interface{}, error) {
}
}

func authorizator() func(data interface{}, c *gin.Context) bool {
return func(data interface{}, c *gin.Context) bool {
func authorizator() func(data any, c *gin.Context) bool {
return func(data any, c *gin.Context) bool {
_, ok := data.(*model.User)
return ok
}
Expand Down
11 changes: 4 additions & 7 deletions cmd/dashboard/controller/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"time"

"github.com/gin-gonic/gin"
"github.com/goccy/go-json"
"github.com/jinzhu/copier"
"gorm.io/gorm"

"github.com/nezhahq/nezha/model"
"github.com/nezhahq/nezha/pkg/utils"
pb "github.com/nezhahq/nezha/proto"
"github.com/nezhahq/nezha/service/singleton"
)
Expand Down Expand Up @@ -81,13 +81,13 @@ func updateServer(c *gin.Context) (any, error) {
s.DDNSProfiles = sf.DDNSProfiles
s.OverrideDDNSDomains = sf.OverrideDDNSDomains

ddnsProfilesRaw, err := utils.Json.Marshal(s.DDNSProfiles)
ddnsProfilesRaw, err := json.Marshal(s.DDNSProfiles)
if err != nil {
return nil, err
}
s.DDNSProfilesRaw = string(ddnsProfilesRaw)

overrideDomainsRaw, err := utils.Json.Marshal(sf.OverrideDDNSDomains)
overrideDomainsRaw, err := json.Marshal(sf.OverrideDDNSDomains)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -281,10 +281,7 @@ func setServerConfig(c *gin.Context) (*model.ServerTaskResponse, error) {
var respMu sync.Mutex

for i := 0; i < len(servers); i += 10 {
end := i + 10
if end > len(servers) {
end = len(servers)
}
end := min(i+10, len(servers))
group := servers[i:end]

wg.Add(1)
Expand Down
6 changes: 3 additions & 3 deletions cmd/dashboard/controller/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
// @Success 200 {object} model.CommonResponse[model.ServiceResponse]
// @Router /service [get]
func showService(c *gin.Context) (*model.ServiceResponse, error) {
res, err, _ := requestGroup.Do("list-service", func() (interface{}, error) {
res, err, _ := requestGroup.Do("list-service", func() (any, error) {
singleton.AlertsLock.RLock()
defer singleton.AlertsLock.RUnlock()
stats := singleton.ServiceSentinelShared.CopyStats()
Expand All @@ -41,8 +41,8 @@ func showService(c *gin.Context) (*model.ServiceResponse, error) {
}

return &model.ServiceResponse{
Services: res.([]interface{})[0].(map[uint64]model.ServiceResponseItem),
CycleTransferStats: res.([]interface{})[1].(map[uint64]model.CycleTransferStats),
Services: res.([]any)[0].(map[uint64]model.ServiceResponseItem),
CycleTransferStats: res.([]any)[1].(map[uint64]model.CycleTransferStats),
}, nil
}

Expand Down
31 changes: 15 additions & 16 deletions cmd/dashboard/controller/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import (
// @Security BearerAuth
// @Tags common
// @Produce json
// @Success 200 {object} model.CommonResponse[model.SettingResponse[model.Config]]
// @Success 200 {object} model.CommonResponse[model.SettingResponse]
// @Router /setting [get]
func listConfig(c *gin.Context) (model.SettingResponse[any], error) {
func listConfig(c *gin.Context) (*model.SettingResponse, error) {
u, authorized := c.Get(model.CtxKeyAuthorizedUser)
var isAdmin bool
if authorized {
Expand All @@ -30,30 +30,29 @@ func listConfig(c *gin.Context) (model.SettingResponse[any], error) {
config := *singleton.Conf
config.Language = strings.Replace(config.Language, "_", "-", -1)

conf := model.SettingResponse[any]{
Config: config,
conf := model.SettingResponse{
Config: model.Setting{
ConfigForGuests: config.ConfigForGuests,
ConfigDashboard: config.ConfigDashboard,
},
Version: singleton.Version,
FrontendTemplates: singleton.FrontendTemplates,
}

if !authorized || !isAdmin {
configForGuests := model.ConfigForGuests{
Language: config.Language,
SiteName: config.SiteName,
CustomCode: config.CustomCode,
CustomCodeDashboard: config.CustomCodeDashboard,
Oauth2Providers: config.Oauth2Providers,
}
configForGuests := config.ConfigForGuests
if authorized {
configForGuests.TLS = singleton.Conf.TLS
configForGuests.AgentTLS = singleton.Conf.AgentTLS
configForGuests.InstallHost = singleton.Conf.InstallHost
}
conf = model.SettingResponse[any]{
Config: configForGuests,
conf = model.SettingResponse{
Config: model.Setting{
ConfigForGuests: configForGuests,
},
}
}

return conf, nil
return &conf, nil
}

// Edit config
Expand Down Expand Up @@ -98,7 +97,7 @@ func updateConfig(c *gin.Context) (any, error) {
singleton.Conf.CustomCode = sf.CustomCode
singleton.Conf.CustomCodeDashboard = sf.CustomCodeDashboard
singleton.Conf.RealIPHeader = sf.RealIPHeader
singleton.Conf.TLS = sf.TLS
singleton.Conf.AgentTLS = sf.AgentTLS
singleton.Conf.UserTemplate = sf.UserTemplate

if err := singleton.Conf.Save(); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions cmd/dashboard/controller/terminal.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"time"

"github.com/gin-gonic/gin"
"github.com/goccy/go-json"
"github.com/gorilla/websocket"
"github.com/hashicorp/go-uuid"

"github.com/nezhahq/nezha/model"
"github.com/nezhahq/nezha/pkg/utils"
"github.com/nezhahq/nezha/pkg/websocketx"
"github.com/nezhahq/nezha/proto"
"github.com/nezhahq/nezha/service/rpc"
Expand Down Expand Up @@ -46,7 +46,7 @@ func createTerminal(c *gin.Context) (*model.CreateTerminalResponse, error) {

rpc.NezhaHandlerSingleton.CreateStream(streamId)

terminalData, _ := utils.Json.Marshal(&model.TerminalTask{
terminalData, _ := json.Marshal(&model.TerminalTask{
StreamID: streamId,
})
if err := server.TaskStream.Send(&proto.Task{
Expand Down
5 changes: 3 additions & 2 deletions cmd/dashboard/controller/ws.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"unicode/utf8"

"github.com/gin-gonic/gin"
"github.com/goccy/go-json"
"github.com/gorilla/websocket"
"github.com/hashicorp/go-uuid"
"golang.org/x/sync/singleflight"
Expand Down Expand Up @@ -157,7 +158,7 @@ func serverStream(c *gin.Context) (any, error) {
var requestGroup singleflight.Group

func getServerStat(withPublicNote, authorized bool) ([]byte, error) {
v, err, _ := requestGroup.Do(fmt.Sprintf("serverStats::%t", authorized), func() (interface{}, error) {
v, err, _ := requestGroup.Do(fmt.Sprintf("serverStats::%t", authorized), func() (any, error) {
var serverList []*model.Server
if authorized {
serverList = singleton.ServerShared.GetSortedList()
Expand All @@ -183,7 +184,7 @@ func getServerStat(withPublicNote, authorized bool) ([]byte, error) {
})
}

return utils.Json.Marshal(model.StreamServerData{
return json.Marshal(model.StreamServerData{
Now: time.Now().Unix() * 1000,
Online: singleton.GetOnlineUserCount(),
Servers: servers,
Expand Down
46 changes: 40 additions & 6 deletions cmd/dashboard/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package main

import (
"context"
"crypto/tls"
"embed"
"errors"
"flag"
"fmt"
"log"
Expand All @@ -16,8 +18,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/ory/graceful"
"golang.org/x/crypto/bcrypt"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"

"github.com/nezhahq/nezha/cmd/dashboard/controller"
"github.com/nezhahq/nezha/cmd/dashboard/controller/waf"
Expand Down Expand Up @@ -133,20 +133,54 @@ func main() {
controller.InitUpgrader()

muxHandler := newHTTPandGRPCMux(httpHandler, grpcHandler)
http2Server := &http2.Server{}
muxServer := &http.Server{Handler: h2c.NewHandler(muxHandler, http2Server), ReadHeaderTimeout: time.Second * 5}
muxServerHTTP := &http.Server{
Handler: muxHandler,
ReadHeaderTimeout: time.Second * 5,
}
muxServerHTTP.Protocols = new(http.Protocols)
muxServerHTTP.Protocols.SetHTTP1(true)
muxServerHTTP.Protocols.SetUnencryptedHTTP2(true)

var muxServerHTTPS *http.Server
if singleton.Conf.HTTPS.ListenPort != 0 {
muxServerHTTPS = &http.Server{
Addr: fmt.Sprintf("%s:%d", singleton.Conf.ListenHost, singleton.Conf.HTTPS.ListenPort),
Handler: muxHandler,
ReadHeaderTimeout: time.Second * 5,
TLSConfig: &tls.Config{
InsecureSkipVerify: singleton.Conf.HTTPS.InsecureTLS,
},
}
}

errChan := make(chan error, 2)

if err := graceful.Graceful(func() error {
log.Printf("NEZHA>> Dashboard::START ON %s:%d", singleton.Conf.ListenHost, singleton.Conf.ListenPort)
return muxServer.Serve(l)
if singleton.Conf.HTTPS.ListenPort != 0 {
go func() {
errChan <- muxServerHTTPS.ListenAndServeTLS(singleton.Conf.HTTPS.TLSCertPath, singleton.Conf.HTTPS.TLSKeyPath)
}()
log.Printf("NEZHA>> Dashboard::START ON %s:%d", singleton.Conf.ListenHost, singleton.Conf.HTTPS.ListenPort)
}
go func() {
errChan <- muxServerHTTP.Serve(l)
}()
return <-errChan
}, func(c context.Context) error {
log.Println("NEZHA>> Graceful::START")
singleton.RecordTransferHourlyUsage()
log.Println("NEZHA>> Graceful::END")
return muxServer.Shutdown(c)
err := muxServerHTTPS.Shutdown(c)
return errors.Join(muxServerHTTP.Shutdown(c), err)
}); err != nil {
log.Printf("NEZHA>> ERROR: %v", err)
if errors.Unwrap(err) != nil {
log.Printf("NEZHA>> ERROR HTTPS: %v", err)
}
}

close(errChan)
}

func newHTTPandGRPCMux(httpHandler http.Handler, grpcHandler http.Handler) http.Handler {
Expand Down
Loading

0 comments on commit 1d2f8d2

Please sign in to comment.