diff --git a/.goreleaser.yml b/.goreleaser.yml index b9496b4..ce40f07 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -26,14 +26,13 @@ builds: binary: nezha-agent universal_binaries: - name_template: "nezha-agent" - replace: true + replace: false checksum: name_template: "checksums.txt" snapshot: name_template: "nezha-agent" archives: - name_template: "nezha-agent_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}" - allow_different_binary_count: true files: - none* changelog: diff --git a/README.md b/README.md index c20930e..ee6648a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
LOGO designed by 熊大 .

-    +   

:trollface: 哪吒监控 一站式轻监控轻运维系统。支持系统状态、HTTP(SSL 证书变更、即将到期、到期)、TCP、Ping 监控报警,计划任务和在线终端。

@@ -45,7 +45,8 @@ _\* 使用 WatchTower 可以自动更新面板,Windows 终端可以使用 nssm - `--report-delay` 系统信息上报的间隔,默认为 1 秒,可以设置为 3 来进一步降低 agent 端系统资源占用(配置区间 1-4) - `--skip-conn` 不监控连接数,机场/连接密集型机器推荐设置,不然比较占 CPU([shirou/gopsutil/issues#220](https://github.com/shirou/gopsutil/issues/220)) - `--skip-procs` 不监控进程数,也可以降低 agent 占用 -- `--disable-auto-update` 禁止 Agent 自动更新(安全特性) +- `--disable-auto-update` 禁止 **自动更新** Agent(安全特性) +- `--disable-force-update` 禁止 **强制更新** Agent(安全特性) - `--disable-command-execute` 禁止在 Agent 机器上执行定时任务、打开在线终端(安全特性) ## 功能说明 diff --git a/cmd/agent/main.go b/cmd/agent/main.go index d5c0579..ecb77b1 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -32,6 +32,7 @@ type AgentConfig struct { SkipConnectionCount bool SkipProcsCount bool DisableAutoUpdate bool + DisableForceUpdate bool DisableCommandExecute bool Debug bool Server string @@ -78,6 +79,7 @@ func main() { flag.BoolVar(&agentConf.SkipProcsCount, "skip-procs", false, "不监控进程数") flag.BoolVar(&agentConf.DisableCommandExecute, "disable-command-execute", false, "禁止在此机器上执行命令") flag.BoolVar(&agentConf.DisableAutoUpdate, "disable-auto-update", false, "禁用自动升级") + flag.BoolVar(&agentConf.DisableForceUpdate, "disable-force-update", false, "禁用强制升级") flag.Parse() if agentConf.ClientSecret == "" { @@ -114,7 +116,7 @@ func run() { time.Sleep(time.Minute * 20) updateCh <- struct{}{} }() - doSelfUpdate() + doSelfUpdate(false) }() } }() @@ -236,8 +238,11 @@ func reportState() { } } -func doSelfUpdate() { - v := semver.MustParse(version) +func doSelfUpdate(donNotUseLocalVersion bool) { + v := semver.MustParse("0.1.0") + if !donNotUseLocalVersion { + v = semver.MustParse(version) + } println("检查更新:", v) latest, err := selfupdate.UpdateSelf(v, "naiba/nezha") if err != nil { @@ -250,7 +255,7 @@ func doSelfUpdate() { } func handleUpgradeTask(task *pb.Task, result *pb.TaskResult) { - doSelfUpdate() + doSelfUpdate(true) } func handleTcpPingTask(task *pb.Task, result *pb.TaskResult) { diff --git a/cmd/dashboard/controller/controller.go b/cmd/dashboard/controller/controller.go index da84af9..4bc7def 100644 --- a/cmd/dashboard/controller/controller.go +++ b/cmd/dashboard/controller/controller.go @@ -4,6 +4,7 @@ import ( "fmt" "html/template" "net/http" + "strconv" "strings" "sync" "time" @@ -28,6 +29,9 @@ func ServeWeb(port uint) *http.Server { "tf": func(t time.Time) string { return t.Format("2006年1月2号 15:04:05") }, + "len": func(slice []interface{}) string { + return strconv.Itoa(len(slice)) + }, "safe": func(s string) template.HTML { return template.HTML(s) // #nosec }, diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go index 5abb35e..f68e684 100644 --- a/cmd/dashboard/controller/member_api.go +++ b/cmd/dashboard/controller/member_api.go @@ -1,6 +1,7 @@ package controller import ( + "bytes" "encoding/json" "errors" "fmt" @@ -14,6 +15,7 @@ import ( "github.com/naiba/nezha/model" "github.com/naiba/nezha/pkg/mygin" "github.com/naiba/nezha/pkg/utils" + "github.com/naiba/nezha/proto" "github.com/naiba/nezha/service/dao" ) @@ -36,6 +38,7 @@ func (ma *memberAPI) serve() { mr.POST("/monitor", ma.addOrEditMonitor) mr.POST("/cron", ma.addOrEditCron) mr.GET("/cron/:id/manual", ma.manualTrigger) + mr.POST("/force-update", ma.forceUpdate) mr.POST("/notification", ma.addOrEditNotification) mr.POST("/alert-rule", ma.addOrEditAlertRule) mr.POST("/setting", ma.updateSetting) @@ -322,6 +325,41 @@ func (ma *memberAPI) manualTrigger(c *gin.Context) { }) } +func (ma *memberAPI) forceUpdate(c *gin.Context) { + var forceUpdateServers []uint64 + if err := c.ShouldBindJSON(&forceUpdateServers); err != nil { + c.JSON(http.StatusOK, model.Response{ + Code: http.StatusBadRequest, + Message: err.Error(), + }) + return + } + + var executeResult bytes.Buffer + + for i := 0; i < len(forceUpdateServers); i++ { + dao.ServerLock.RLock() + server := dao.ServerList[forceUpdateServers[i]] + dao.ServerLock.RUnlock() + if server != nil && server.TaskStream != nil { + if err := server.TaskStream.Send(&proto.Task{ + Type: model.TaskTypeUpgrade, + }); err != nil { + executeResult.WriteString(fmt.Sprintf("%d 下发指令失败 %+v
", forceUpdateServers[i], err)) + } else { + executeResult.WriteString(fmt.Sprintf("%d 下发指令成功
", forceUpdateServers[i])) + } + } else { + executeResult.WriteString(fmt.Sprintf("%d 离线
", forceUpdateServers[i])) + } + } + + c.JSON(http.StatusOK, model.Response{ + Code: http.StatusOK, + Message: executeResult.String(), + }) +} + type notificationForm struct { ID uint64 Name string diff --git a/go.mod b/go.mod index 8cc6e39..1422801 100644 --- a/go.mod +++ b/go.mod @@ -23,14 +23,13 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 // indirect github.com/robfig/cron/v3 v3.0.1 - github.com/shirou/gopsutil/v3 v3.21.8 + github.com/shirou/gopsutil/v3 v3.21.10 github.com/spf13/pflag v1.0.3 github.com/spf13/viper v1.7.1 github.com/stretchr/testify v1.7.0 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 // indirect golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 - golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect google.golang.org/grpc v1.33.1 google.golang.org/protobuf v1.25.0 gopkg.in/yaml.v2 v2.2.8 diff --git a/go.sum b/go.sum index b03b7c9..f31182c 100644 --- a/go.sum +++ b/go.sum @@ -94,8 +94,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741 h1:b0sLP++Tsle+s57tqg5sUk1/OQsC6yMCciVeqNzOcwU= github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741/go.mod h1:35JbSyV/BYqHwwRA6Zr1uVDm1637YlNOU61wI797NPI= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= @@ -144,8 +145,9 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= @@ -225,6 +227,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -290,8 +294,8 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shirou/gopsutil/v3 v3.21.8 h1:nKct+uP0TV8DjjNiHanKf8SAuub+GNsbrOtM9Nl9biA= -github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ= +github.com/shirou/gopsutil/v3 v3.21.10 h1:flTg1DrnV/UVrBqjLgVgDJzx6lf+91rC64/dBHmO2IA= +github.com/shirou/gopsutil/v3 v3.21.10/go.mod h1:t75NhzCZ/dYyPQjyQmrAYP6c8+LCdFANeBMdLPCNnew= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -470,8 +474,8 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/resource/template/dashboard/server.html b/resource/template/dashboard/server.html index 1fc31e1..3b27046 100644 --- a/resource/template/dashboard/server.html +++ b/resource/template/dashboard/server.html @@ -8,11 +8,15 @@ + + @@ -27,6 +31,7 @@ {{range $server := .Servers}} + @@ -72,5 +77,57 @@ {{end}} \ No newline at end of file diff --git a/service/dao/dao.go b/service/dao/dao.go index c3beb78..18a9e72 100644 --- a/service/dao/dao.go +++ b/service/dao/dao.go @@ -13,7 +13,7 @@ import ( pb "github.com/naiba/nezha/proto" ) -var Version = "v0.10.6" // !!记得修改 README 中的 badge 版本!! +var Version = "v0.10.7" // !!记得修改 README 中的 badge 版本!! var ( Conf *model.Config
ID(排序) 名称 分组
{{$server.ID}}({{$server.DisplayIndex}}) {{$server.Name}} {{$server.Tag}}