Skip to content

Commit

Permalink
refactor: simplify server & service manipulation (#993)
Browse files Browse the repository at this point in the history
* refactor: simplify server & service manipulation

* update

* fix

* update for nat, ddns & notification

* chore

* update cron

* update dependencies

* use of function iterators

* update default dns servers
  • Loading branch information
uubulb authored Feb 21, 2025
1 parent 21eefde commit 91bef28
Show file tree
Hide file tree
Showing 32 changed files with 976 additions and 1,072 deletions.
12 changes: 3 additions & 9 deletions cmd/dashboard/controller/alertrule.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controller

import (
"maps"
"strconv"
"time"

Expand Down Expand Up @@ -168,16 +169,9 @@ func batchDeleteAlertRule(c *gin.Context) (any, error) {
func validateRule(c *gin.Context, r *model.AlertRule) error {
if len(r.Rules) > 0 {
for _, rule := range r.Rules {
singleton.ServerLock.RLock()
for s := range rule.Ignore {
if server, ok := singleton.ServerList[s]; ok {
if !server.HasPermission(c) {
singleton.ServerLock.RUnlock()
return singleton.Localizer.ErrorT("permission denied")
}
}
if !singleton.ServerShared.CheckPermission(c, maps.Keys(rule.Ignore)) {
return singleton.Localizer.ErrorT("permission denied")
}
singleton.ServerLock.RUnlock()

if !rule.IsTransferDurationRule() {
if rule.Duration < 3 {
Expand Down
57 changes: 15 additions & 42 deletions cmd/dashboard/controller/cron.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controller

import (
"slices"
"strconv"

"github.com/gin-gonic/gin"
Expand All @@ -21,11 +22,10 @@ import (
// @Success 200 {object} model.CommonResponse[[]model.Cron]
// @Router /cron [get]
func listCron(c *gin.Context) ([]*model.Cron, error) {
singleton.CronLock.RLock()
defer singleton.CronLock.RUnlock()
slist := singleton.CronShared.GetSortedList()

var cr []*model.Cron
if err := copier.Copy(&cr, &singleton.CronList); err != nil {
if err := copier.Copy(&cr, &slist); err != nil {
return nil, err
}
return cr, nil
Expand All @@ -50,16 +50,9 @@ func createCron(c *gin.Context) (uint64, error) {
return 0, err
}

singleton.ServerLock.RLock()
for _, sid := range cf.Servers {
if server, ok := singleton.ServerList[sid]; ok {
if !server.HasPermission(c) {
singleton.ServerLock.RUnlock()
return 0, singleton.Localizer.ErrorT("permission denied")
}
}
if !singleton.ServerShared.CheckPermission(c, slices.Values(cf.Servers)) {
return 0, singleton.Localizer.ErrorT("permission denied")
}
singleton.ServerLock.RUnlock()

cr.UserID = getUid(c)
cr.TaskType = cf.TaskType
Expand All @@ -78,7 +71,7 @@ func createCron(c *gin.Context) (uint64, error) {
// 对于计划任务类型,需要更新CronJob
var err error
if cf.TaskType == model.CronTypeCronTask {
if cr.CronJobID, err = singleton.Cron.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
if cr.CronJobID, err = singleton.CronShared.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
return 0, err
}
}
Expand All @@ -87,8 +80,7 @@ func createCron(c *gin.Context) (uint64, error) {
return 0, newGormError("%v", err)
}

singleton.OnRefreshOrAddCron(&cr)
singleton.UpdateCronList()
singleton.CronShared.Update(&cr)
return cr.ID, nil
}

Expand Down Expand Up @@ -116,16 +108,9 @@ func updateCron(c *gin.Context) (any, error) {
return 0, err
}

singleton.ServerLock.RLock()
for _, sid := range cf.Servers {
if server, ok := singleton.ServerList[sid]; ok {
if !server.HasPermission(c) {
singleton.ServerLock.RUnlock()
return nil, singleton.Localizer.ErrorT("permission denied")
}
}
if !singleton.ServerShared.CheckPermission(c, slices.Values(cf.Servers)) {
return 0, singleton.Localizer.ErrorT("permission denied")
}
singleton.ServerLock.RUnlock()

var cr model.Cron
if err := singleton.DB.First(&cr, id).Error; err != nil {
Expand All @@ -151,7 +136,7 @@ func updateCron(c *gin.Context) (any, error) {

// 对于计划任务类型,需要更新CronJob
if cf.TaskType == model.CronTypeCronTask {
if cr.CronJobID, err = singleton.Cron.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
if cr.CronJobID, err = singleton.CronShared.AddFunc(cr.Scheduler, singleton.CronTrigger(&cr)); err != nil {
return nil, err
}
}
Expand All @@ -160,8 +145,7 @@ func updateCron(c *gin.Context) (any, error) {
return nil, newGormError("%v", err)
}

singleton.OnRefreshOrAddCron(&cr)
singleton.UpdateCronList()
singleton.CronShared.Update(&cr)
return nil, nil
}

Expand All @@ -183,13 +167,10 @@ func manualTriggerCron(c *gin.Context) (any, error) {
return nil, err
}

singleton.CronLock.RLock()
cr, ok := singleton.Crons[id]
cr, ok := singleton.CronShared.Get(id)
if !ok {
singleton.CronLock.RUnlock()
return nil, singleton.Localizer.ErrorT("task id %d does not exist", id)
}
singleton.CronLock.RUnlock()

if !cr.HasPermission(c) {
return nil, singleton.Localizer.ErrorT("permission denied")
Expand All @@ -216,22 +197,14 @@ func batchDeleteCron(c *gin.Context) (any, error) {
return nil, err
}

singleton.CronLock.RLock()
for _, crID := range cr {
if crn, ok := singleton.Crons[crID]; ok {
if !crn.HasPermission(c) {
singleton.CronLock.RUnlock()
return nil, singleton.Localizer.ErrorT("permission denied")
}
}
if !singleton.CronShared.CheckPermission(c, slices.Values(cr)) {
return nil, singleton.Localizer.ErrorT("permission denied")
}
singleton.CronLock.RUnlock()

if err := singleton.DB.Unscoped().Delete(&model.Cron{}, "id in (?)", cr).Error; err != nil {
return nil, newGormError("%v", err)
}

singleton.OnDeleteCron(cr)
singleton.UpdateCronList()
singleton.CronShared.Delete(cr)
return nil, nil
}
29 changes: 8 additions & 21 deletions cmd/dashboard/controller/ddns.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controller

import (
"slices"
"strconv"

"github.com/gin-gonic/gin"
Expand All @@ -24,10 +25,8 @@ import (
func listDDNS(c *gin.Context) ([]*model.DDNSProfile, error) {
var ddnsProfiles []*model.DDNSProfile

singleton.DDNSListLock.RLock()
defer singleton.DDNSListLock.RUnlock()

if err := copier.Copy(&ddnsProfiles, &singleton.DDNSList); err != nil {
list := singleton.DDNSShared.GetSortedList()
if err := copier.Copy(&ddnsProfiles, &list); err != nil {
return nil, err
}

Expand Down Expand Up @@ -87,9 +86,7 @@ func createDDNS(c *gin.Context) (uint64, error) {
return 0, newGormError("%v", err)
}

singleton.OnDDNSUpdate(&p)
singleton.UpdateDDNSList()

singleton.DDNSShared.Update(&p)
return p.ID, nil
}

Expand Down Expand Up @@ -160,8 +157,7 @@ func updateDDNS(c *gin.Context) (any, error) {
return nil, newGormError("%v", err)
}

singleton.OnDDNSUpdate(&p)
singleton.UpdateDDNSList()
singleton.DDNSShared.Update(&p)

return nil, nil
}
Expand All @@ -184,24 +180,15 @@ func batchDeleteDDNS(c *gin.Context) (any, error) {
return nil, err
}

singleton.DDNSCacheLock.RLock()
for _, pid := range ddnsConfigs {
if p, ok := singleton.DDNSCache[pid]; ok {
if !p.HasPermission(c) {
singleton.DDNSCacheLock.RUnlock()
return nil, singleton.Localizer.ErrorT("permission denied")
}
}
if !singleton.DDNSShared.CheckPermission(c, slices.Values(ddnsConfigs)) {
return nil, singleton.Localizer.ErrorT("permission denied")
}
singleton.DDNSCacheLock.RUnlock()

if err := singleton.DB.Unscoped().Delete(&model.DDNSProfile{}, "id in (?)", ddnsConfigs).Error; err != nil {
return nil, newGormError("%v", err)
}

singleton.OnDDNSDelete(ddnsConfigs)
singleton.UpdateDDNSList()

singleton.DDNSShared.Delete(ddnsConfigs)
return nil, nil
}

Expand Down
4 changes: 1 addition & 3 deletions cmd/dashboard/controller/fm.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ func createFM(c *gin.Context) (*model.CreateFMResponse, error) {
return nil, err
}

singleton.ServerLock.RLock()
server := singleton.ServerList[id]
singleton.ServerLock.RUnlock()
server, _ := singleton.ServerShared.Get(id)
if server == nil || server.TaskStream == nil {
return nil, singleton.Localizer.ErrorT("server not found or not connected")
}
Expand Down
40 changes: 14 additions & 26 deletions cmd/dashboard/controller/nat.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package controller

import (
"slices"
"strconv"

"github.com/gin-gonic/gin"
"github.com/jinzhu/copier"

"github.com/nezhahq/nezha/model"
"github.com/nezhahq/nezha/pkg/utils"
"github.com/nezhahq/nezha/service/singleton"
)

Expand All @@ -23,10 +25,9 @@ import (
func listNAT(c *gin.Context) ([]*model.NAT, error) {
var n []*model.NAT

singleton.NATListLock.RLock()
defer singleton.NATListLock.RUnlock()
slist := singleton.NATShared.GetSortedList()

if err := copier.Copy(&n, &singleton.NATList); err != nil {
if err := copier.Copy(&n, &slist); err != nil {
return nil, err
}

Expand All @@ -52,14 +53,11 @@ func createNAT(c *gin.Context) (uint64, error) {
return 0, err
}

singleton.ServerLock.RLock()
if server, ok := singleton.ServerList[nf.ServerID]; ok {
if server, ok := singleton.ServerShared.Get(nf.ServerID); ok {
if !server.HasPermission(c) {
singleton.ServerLock.RUnlock()
return 0, singleton.Localizer.ErrorT("permission denied")
}
}
singleton.ServerLock.RUnlock()

uid := getUid(c)

Expand All @@ -74,8 +72,7 @@ func createNAT(c *gin.Context) (uint64, error) {
return 0, newGormError("%v", err)
}

singleton.OnNATUpdate(&n)
singleton.UpdateNATList()
singleton.NATShared.Update(&n)
return n.ID, nil
}

Expand Down Expand Up @@ -104,14 +101,11 @@ func updateNAT(c *gin.Context) (any, error) {
return nil, err
}

singleton.ServerLock.RLock()
if server, ok := singleton.ServerList[nf.ServerID]; ok {
if server, ok := singleton.ServerShared.Get(nf.ServerID); ok {
if !server.HasPermission(c) {
singleton.ServerLock.RUnlock()
return nil, singleton.Localizer.ErrorT("permission denied")
}
}
singleton.ServerLock.RUnlock()

var n model.NAT
if err = singleton.DB.First(&n, id).Error; err != nil {
Expand All @@ -132,8 +126,7 @@ func updateNAT(c *gin.Context) (any, error) {
return 0, newGormError("%v", err)
}

singleton.OnNATUpdate(&n)
singleton.UpdateNATList()
singleton.NATShared.Update(&n)
return nil, nil
}

Expand All @@ -154,22 +147,17 @@ func batchDeleteNAT(c *gin.Context) (any, error) {
return nil, err
}

singleton.NATCacheRwLock.RLock()
for _, id := range n {
if p, ok := singleton.NATCache[singleton.NATIDToDomain[id]]; ok {
if !p.HasPermission(c) {
singleton.NATCacheRwLock.RUnlock()
return nil, singleton.Localizer.ErrorT("permission denied")
}
}
if !singleton.NATShared.CheckPermission(c, utils.ConvertSeq(slices.Values(n),
func(id uint64) string {
return singleton.NATShared.GetDomain(id)
})) {
return nil, singleton.Localizer.ErrorT("permission denied")
}
singleton.NATCacheRwLock.RUnlock()

if err := singleton.DB.Unscoped().Delete(&model.NAT{}, "id in (?)", n).Error; err != nil {
return nil, newGormError("%v", err)
}

singleton.OnNATDelete(n)
singleton.UpdateNATList()
singleton.NATShared.Delete(n)
return nil, nil
}
Loading

0 comments on commit 91bef28

Please sign in to comment.