diff --git a/build/configs/server.template.yaml b/build/configs/server.template.yaml index f6ea5e8f..81d2e8bf 100644 --- a/build/configs/server.template.yaml +++ b/build/configs/server.template.yaml @@ -4,7 +4,7 @@ env: prod # http http: "on": true - listen: [ "0.0.0.0:8001" ] + listen: [ "0.0.0.0:7788" ] # https https: diff --git a/go.mod b/go.mod index f6a62359..aab24f69 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/go-redis/redis v6.15.8+incompatible // indirect github.com/go-yaml/yaml v2.1.0+incompatible github.com/golang/protobuf v1.4.2 // indirect - github.com/iwind/TeaGo v0.0.0-20200910072805-729cffe36729 + github.com/iwind/TeaGo v0.0.0-20200924024009-d088df3778a6 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 // indirect diff --git a/go.sum b/go.sum index e445c467..007d83c7 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,10 @@ github.com/iwind/TeaGo v0.0.0-20200909062051-96811444bb22 h1:bCv4Emo49CZyZFbnq9l github.com/iwind/TeaGo v0.0.0-20200909062051-96811444bb22/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc= github.com/iwind/TeaGo v0.0.0-20200910072805-729cffe36729 h1:/v0WhSFVeNay/dA5zU9iCBXlgVDfxnztuanlauXE0gM= github.com/iwind/TeaGo v0.0.0-20200910072805-729cffe36729/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc= +github.com/iwind/TeaGo v0.0.0-20200923021120-f5d76441fe9e h1:/xn7wUvlwaoA5IkdBUctv2OQbJSZ0/Dw8qRJmn55sJk= +github.com/iwind/TeaGo v0.0.0-20200923021120-f5d76441fe9e/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc= +github.com/iwind/TeaGo v0.0.0-20200924024009-d088df3778a6 h1:7OZC/Qy7Z/hK9vG6YQOwHNOUPunSImYYJMiIfvuDQZ0= +github.com/iwind/TeaGo v0.0.0-20200924024009-d088df3778a6/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= diff --git a/internal/configs/nodes/node_status.go b/internal/configs/nodes/node_status.go index 72291400..3c531ff8 100644 --- a/internal/configs/nodes/node_status.go +++ b/internal/configs/nodes/node_status.go @@ -2,6 +2,9 @@ package nodes // 节点状态 type NodeStatus struct { + BuildVersion string `json:"buildVersion"` // 编译版本 + ConfigVersion int64 `json:"configVersion"` // 节点配置版本 + Hostname string `json:"hostname"` HostIP string `json:"hostIP"` CPUUsage float64 `json:"cpuUsage"` diff --git a/internal/web/actions/default/clusters/cluster/index.go b/internal/web/actions/default/clusters/cluster/index.go index 288bb791..4bbc42f6 100644 --- a/internal/web/actions/default/clusters/cluster/index.go +++ b/internal/web/actions/default/clusters/cluster/index.go @@ -4,8 +4,8 @@ import ( "encoding/json" "fmt" "github.com/TeaOSLab/EdgeAdmin/internal/configs/nodes" - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/types" @@ -24,12 +24,15 @@ func (this *IndexAction) Init() { func (this *IndexAction) RunGet(params struct { ClusterId int64 InstalledState int + ActiveState int }) { this.Data["installState"] = params.InstalledState + this.Data["activeState"] = params.ActiveState countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{ ClusterId: params.ClusterId, InstallState: types.Int32(params.InstalledState), + ActiveState: types.Int32(params.ActiveState), }) if err != nil { this.ErrorPage(err) @@ -44,10 +47,12 @@ func (this *IndexAction) RunGet(params struct { Size: page.Size, ClusterId: params.ClusterId, InstallState: types.Int32(params.InstalledState), + ActiveState: types.Int32(params.ActiveState), }) nodeMaps := []maps.Map{} for _, node := range nodesResp.Nodes { // 状态 + isSynced := false status := &nodes.NodeStatus{} if len(node.Status) > 0 && node.Status != "null" { err = json.Unmarshal([]byte(node.Status), &status) @@ -55,7 +60,8 @@ func (this *IndexAction) RunGet(params struct { logs.Error(err) continue } - status.IsActive = time.Now().Unix()-status.UpdatedAt < 120 // 2分钟之内认为活跃 + status.IsActive = time.Now().Unix()-status.UpdatedAt <= 60 // N秒之内认为活跃 + isSynced = status.ConfigVersion == node.Version } // IP @@ -96,6 +102,7 @@ func (this *IndexAction) RunGet(params struct { "id": node.Cluster.Id, "name": node.Cluster.Name, }, + "isSynced": isSynced, "ipAddresses": ipAddresses, }) } diff --git a/internal/web/actions/default/clusters/index.go b/internal/web/actions/default/clusters/index.go index d0fde1c4..7a1987bb 100644 --- a/internal/web/actions/default/clusters/index.go +++ b/internal/web/actions/default/clusters/index.go @@ -1,9 +1,11 @@ package clusters import ( - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/configutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/maps" + "github.com/iwind/TeaGo/types" ) type IndexAction struct { @@ -35,19 +37,30 @@ func (this *IndexAction) RunGet(params struct{}) { return } for _, cluster := range clustersResp.Clusters { - // 节点数量 + // 全部节点数量 countNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{ClusterId: cluster.Id}) if err != nil { this.ErrorPage(err) return } + // 在线节点 + countActiveNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{ + ClusterId: cluster.Id, + ActiveState: types.Int32(configutils.BoolStateYes), + }) + if err != nil { + this.ErrorPage(err) + return + } + clusterMaps = append(clusterMaps, maps.Map{ - "id": cluster.Id, - "name": cluster.Name, - "installDir": cluster.InstallDir, - "hasGrant": cluster.GrantId > 0, - "countNodes": countNodesResp.Count, + "id": cluster.Id, + "name": cluster.Name, + "installDir": cluster.InstallDir, + "hasGrant": cluster.GrantId > 0, + "countAllNodes": countNodesResp.Count, + "countActiveNodes": countActiveNodesResp.Count, }) } } diff --git a/internal/web/actions/default/common/changedClusters.go b/internal/web/actions/default/common/changedClusters.go index 2d09f938..443b3fa2 100644 --- a/internal/web/actions/default/common/changedClusters.go +++ b/internal/web/actions/default/common/changedClusters.go @@ -1,11 +1,13 @@ package common import ( - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/maps" + "time" ) +// 检查变更的集群列表 type ChangedClustersAction struct { actionutils.ParentAction } @@ -14,22 +16,50 @@ func (this *ChangedClustersAction) Init() { this.Nav("", "", "") } -func (this *ChangedClustersAction) RunGet(params struct{}) { - resp, err := this.RPC().NodeClusterRPC().FindAllChangedNodeClusters(this.AdminContext(), &pb.FindAllChangedNodeClustersRequest{}) - if err != nil { - this.ErrorPage(err) - return - } +func (this *ChangedClustersAction) RunGet(params struct { + IsNotifying bool +}) { + timeout := time.NewTimer(55 * time.Second) // 比客户端提前结束,避免在客户端产生一个请求错误 - result := []maps.Map{} - for _, cluster := range resp.Clusters { - result = append(result, maps.Map{ - "id": cluster.Id, - "name": cluster.Name, - }) - } + this.Data["clusters"] = []interface{}{} - this.Data["clusters"] = result +Loop: + for { + select { + case <-this.Request.Context().Done(): + break Loop + case <-timeout.C: + break Loop + default: + // 继续 + } + + resp, err := this.RPC().NodeClusterRPC().FindAllChangedNodeClusters(this.AdminContext(), &pb.FindAllChangedNodeClustersRequest{}) + if err != nil { + this.ErrorPage(err) + return + } + + result := []maps.Map{} + for _, cluster := range resp.Clusters { + result = append(result, maps.Map{ + "id": cluster.Id, + "name": cluster.Name, + }) + } + + // 从提醒到提醒消失 + if len(result) == 0 && params.IsNotifying { + break + } + + this.Data["clusters"] = result + if len(result) > 0 { + break + } + + time.Sleep(1 * time.Second) + } this.Success() } diff --git a/internal/web/actions/default/common/syncClusters.go b/internal/web/actions/default/common/syncClusters.go index 6df7857b..83ab40aa 100644 --- a/internal/web/actions/default/common/syncClusters.go +++ b/internal/web/actions/default/common/syncClusters.go @@ -1,10 +1,11 @@ package common import ( - "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" ) +// 同步集群 type SyncClustersAction struct { actionutils.ParentAction } diff --git a/internal/web/actions/default/servers/server/settings/charset/index.go b/internal/web/actions/default/servers/server/settings/charset/index.go index 979925f5..0adbb1fb 100644 --- a/internal/web/actions/default/servers/server/settings/charset/index.go +++ b/internal/web/actions/default/servers/server/settings/charset/index.go @@ -3,8 +3,8 @@ package charset import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/webutils" + "github.com/TeaOSLab/EdgeCommon/pkg/configutils" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" - "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils" "github.com/iwind/TeaGo/actions" ) diff --git a/internal/web/actions/default/servers/server/settings/headers/createDeletePopup.go b/internal/web/actions/default/servers/server/settings/headers/createDeletePopup.go index 950b1a77..975e0196 100644 --- a/internal/web/actions/default/servers/server/settings/headers/createDeletePopup.go +++ b/internal/web/actions/default/servers/server/settings/headers/createDeletePopup.go @@ -42,7 +42,7 @@ func (this *CreateDeletePopupAction) RunPost(params struct { return } - deleteHeaders := policyConfig.DeletedHeaders + deleteHeaders := policyConfig.DeleteHeaders deleteHeaders = append(deleteHeaders, params.Name) _, err = this.RPC().HTTPHeaderPolicyRPC().UpdateHTTPHeaderPolicyDeletingHeaders(this.AdminContext(), &pb.UpdateHTTPHeaderPolicyDeletingHeadersRequest{ HeaderPolicyId: params.HeaderPolicyId, diff --git a/internal/web/actions/default/servers/server/settings/headers/createSetPopup.go b/internal/web/actions/default/servers/server/settings/headers/createSetPopup.go index d76570f5..0a15fe9c 100644 --- a/internal/web/actions/default/servers/server/settings/headers/createSetPopup.go +++ b/internal/web/actions/default/servers/server/settings/headers/createSetPopup.go @@ -60,14 +60,12 @@ func (this *CreateSetPopupAction) RunPost(params struct { headerId := createHeaderResp.HeaderId // 保存 - policyConfig.SetHeaders = append(policyConfig.SetHeaders, &shared.HTTPHeaderConfig{ - Id: headerId, - IsOn: true, - Name: params.Name, - Value: params.Value, - Status: nil, + refs := policyConfig.SetHeaderRefs + refs = append(refs, &shared.HTTPHeaderRef{ + IsOn: true, + HeaderId: headerId, }) - setHeadersJSON, err := json.Marshal(policyConfig.SetHeaders) + refsJSON, err := json.Marshal(refs) if err != nil { this.ErrorPage(err) return @@ -75,7 +73,7 @@ func (this *CreateSetPopupAction) RunPost(params struct { _, err = this.RPC().HTTPHeaderPolicyRPC().UpdateHTTPHeaderPolicySettingHeaders(this.AdminContext(), &pb.UpdateHTTPHeaderPolicySettingHeadersRequest{ HeaderPolicyId: params.HeaderPolicyId, - HeadersJSON: setHeadersJSON, + HeadersJSON: refsJSON, }) if err != nil { this.ErrorPage(err) diff --git a/internal/web/actions/default/servers/server/settings/headers/delete.go b/internal/web/actions/default/servers/server/settings/headers/delete.go index 8799870c..ddc0c179 100644 --- a/internal/web/actions/default/servers/server/settings/headers/delete.go +++ b/internal/web/actions/default/servers/server/settings/headers/delete.go @@ -33,9 +33,9 @@ func (this *DeleteAction) RunPost(params struct { switch params.Type { case "addHeader": - result := []*shared.HTTPHeaderConfig{} - for _, h := range policyConfig.AddHeaders { - if h.Id != params.HeaderId { + result := []*shared.HTTPHeaderRef{} + for _, h := range policyConfig.AddHeaderRefs { + if h.HeaderId != params.HeaderId { result = append(result, h) } } @@ -53,9 +53,9 @@ func (this *DeleteAction) RunPost(params struct { return } case "setHeader": - result := []*shared.HTTPHeaderConfig{} - for _, h := range policyConfig.SetHeaders { - if h.Id != params.HeaderId { + result := []*shared.HTTPHeaderRef{} + for _, h := range policyConfig.SetHeaderRefs { + if h.HeaderId != params.HeaderId { result = append(result, h) } } @@ -73,9 +73,9 @@ func (this *DeleteAction) RunPost(params struct { return } case "replace": - result := []*shared.HTTPHeaderConfig{} - for _, h := range policyConfig.ReplaceHeaders { - if h.Id != params.HeaderId { + result := []*shared.HTTPHeaderRef{} + for _, h := range policyConfig.ReplaceHeaderRefs { + if h.HeaderId != params.HeaderId { result = append(result, h) } } @@ -93,9 +93,9 @@ func (this *DeleteAction) RunPost(params struct { return } case "addTrailer": - result := []*shared.HTTPHeaderConfig{} - for _, h := range policyConfig.AddTrailers { - if h.Id != params.HeaderId { + result := []*shared.HTTPHeaderRef{} + for _, h := range policyConfig.AddTrailerRefs { + if h.HeaderId != params.HeaderId { result = append(result, h) } } diff --git a/internal/web/actions/default/servers/server/settings/headers/deleteDeletingHeader.go b/internal/web/actions/default/servers/server/settings/headers/deleteDeletingHeader.go index dda8ed67..442d5805 100644 --- a/internal/web/actions/default/servers/server/settings/headers/deleteDeletingHeader.go +++ b/internal/web/actions/default/servers/server/settings/headers/deleteDeletingHeader.go @@ -29,7 +29,7 @@ func (this *DeleteDeletingHeaderAction) RunPost(params struct { } headerNames := []string{} - for _, h := range policyConfig.DeletedHeaders { + for _, h := range policyConfig.DeleteHeaders { if h == params.HeaderName { continue } diff --git a/internal/web/actions/default/servers/server/settings/locations/charset/index.go b/internal/web/actions/default/servers/server/settings/locations/charset/index.go index 377a7017..e2c4442c 100644 --- a/internal/web/actions/default/servers/server/settings/locations/charset/index.go +++ b/internal/web/actions/default/servers/server/settings/locations/charset/index.go @@ -3,8 +3,8 @@ package charset import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/webutils" + "github.com/TeaOSLab/EdgeCommon/pkg/configutils" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" - "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/configutils" "github.com/iwind/TeaGo/actions" ) diff --git a/internal/web/actions/default/servers/serverutils/server_helper.go b/internal/web/actions/default/servers/serverutils/server_helper.go index 42eebde6..d9b30fc1 100644 --- a/internal/web/actions/default/servers/serverutils/server_helper.go +++ b/internal/web/actions/default/servers/serverutils/server_helper.go @@ -78,7 +78,7 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) { // TABBAR selectedTabbar, _ := action.Data["mainTab"] tabbar := actionutils.NewTabbar() - tabbar.Add("当前服务:"+serverConfig.Name, "", "/servers", "left long alternate arrow", false) + tabbar.Add("当前服务:"+server.Name, "", "/servers", "left long alternate arrow", false) //tabbar.Add("看板", "", "/servers/server/board?serverId="+serverIdString, "dashboard", selectedTabbar == "board") tabbar.Add("日志", "", "/servers/server/log?serverId="+serverIdString, "history", selectedTabbar == "log") //tabbar.Add("统计", "", "/servers/server/stat?serverId="+serverIdString, "chart area", selectedTabbar == "stat") diff --git a/web/public/js/components/common/more-options-angle.js b/web/public/js/components/common/more-options-angle.js new file mode 100644 index 00000000..e2b0bde9 --- /dev/null +++ b/web/public/js/components/common/more-options-angle.js @@ -0,0 +1,14 @@ +Vue.component("more-options-angle", { + data: function () { + return { + isVisible: false + } + }, + methods: { + show: function () { + this.isVisible = !this.isVisible + this.$emit("change", this.isVisible) + } + }, + template: `更多选项收起选项` +}) \ No newline at end of file diff --git a/web/public/js/components/server/http-header-policy-box.js b/web/public/js/components/server/http-header-policy-box.js index 4122a2ff..dc2ac3d4 100644 --- a/web/public/js/components/server/http-header-policy-box.js +++ b/web/public/js/components/server/http-header-policy-box.js @@ -53,7 +53,7 @@ Vue.component("http-header-policy-box", { responseDeletingHeaders = responsePolicy.deleteHeaders } } - + return { type: type, typeName: (type == "request") ? "请求" : "响应", diff --git a/web/public/js/components/server/http-pages-and-shutdown-box.js b/web/public/js/components/server/http-pages-and-shutdown-box.js index 39f58e0e..5da1dd07 100644 --- a/web/public/js/components/server/http-pages-and-shutdown-box.js +++ b/web/public/js/components/server/http-pages-and-shutdown-box.js @@ -1,11 +1,12 @@ Vue.component("http-pages-and-shutdown-box", { - props: ["v-pages", "v-shutdown-config"], + props: ["v-pages", "v-shutdown-config", "v-is-location"], data: function () { let pages = [] if (this.vPages != null) { pages = this.vPages } let shutdownConfig = { + isPrior: false, isOn: false, url: "", status: 0 @@ -84,25 +85,33 @@ Vue.component("http-pages-and-shutdown-box", {
| 是否开启 | +
+
+
+
+
+ |
+
| 页面URL |
- 页面文件是相对于节点安装目录的页面文件比如web/pages/40x.html,或者一个完整的URL。 +页面文件是相对于节点安装目录的页面文件比如pages/40x.html,或者一个完整的URL。 |
| 状态码 |
开启临时关闭页面时,所有请求的响应都会显示此页面。可用于临时升级网站使用。
开启后,所有HTTP的请求都会自动跳转到对应的HTTPS URL上。
+开启后,所有HTTP的请求都会自动跳转到对应的HTTPS URL上,
| 状态码 | ++ + | +
| 域名或IP地址 | +
+
+ 默认和用户正在访问的域名或IP地址一致。 + |
+
| 端口 | +
+
+ 默认端口为443。 + |
+
开启后,所有HTTP的请求都会自动跳转到对应的HTTPS URL上。
+开启后,所有HTTP的请求都会自动跳转到对应的HTTPS URL上,
| 状态码 | ++ + | +
| 域名或IP地址 | +
+
+ 默认和用户正在访问的域名或IP地址一致。 + |
+
| 端口 | +
+
+ 默认端口为443。 + |
+