diff --git a/EdgeAPI/build/build.sh b/EdgeAPI/build/build.sh
index 9c58075..57f19b2 100644
--- a/EdgeAPI/build/build.sh
+++ b/EdgeAPI/build/build.sh
@@ -128,13 +128,11 @@ function build() {
# copy files
echo "copying ..."
- if [ ! -d "$DIST" ]; then
- mkdir "$DIST"
- mkdir "$DIST"/bin
- mkdir "$DIST"/configs
- mkdir "$DIST"/logs
- mkdir "$DIST"/data
- fi
+ rm -rf "$DIST"
+ mkdir -p "$DIST"/bin
+ mkdir -p "$DIST"/configs
+ mkdir -p "$DIST"/logs
+ mkdir -p "$DIST"/data
cp "$ROOT"/configs/api.template.yaml "$DIST"/configs/
cp "$ROOT"/configs/db.template.yaml "$DIST"/configs/
# 复制 EdgeCommon 的配置文件(如果存在)
@@ -148,42 +146,6 @@ function build() {
rm -f "$DIST"/deploy/.gitignore
cp -R "$ROOT"/installers "$DIST"/
- # copy fluent-bit templates and local packages from repo root
- FLUENT_ROOT="$ROOT/../../deploy/fluent-bit"
- FLUENT_DIST="$DIST/deploy/fluent-bit"
- if [ -d "$FLUENT_ROOT" ]; then
- rm -rf "$FLUENT_DIST"
- mkdir -p "$FLUENT_DIST"
-
- FLUENT_FILES=(
- "fluent-bit.conf"
- "fluent-bit-dns.conf"
- "fluent-bit-https.conf"
- "fluent-bit-dns-https.conf"
- "fluent-bit-windows.conf"
- "fluent-bit-windows-https.conf"
- "parsers.conf"
- "clickhouse-upstream.conf"
- "clickhouse-upstream-windows.conf"
- "logrotate.conf"
- "README.md"
- )
- for file in "${FLUENT_FILES[@]}"; do
- if [ -f "$FLUENT_ROOT/$file" ]; then
- cp "$FLUENT_ROOT/$file" "$FLUENT_DIST/"
- fi
- done
-
- if [ -d "$FLUENT_ROOT/packages" ]; then
- cp -R "$FLUENT_ROOT/packages" "$FLUENT_DIST/"
- fi
-
- # remove local runtime artifacts if present
- rm -f "$FLUENT_DIST/.gitignore"
- rm -f "$FLUENT_DIST"/logs.db*
- rm -rf "$FLUENT_DIST/storage"
- fi
-
# building edge installer
echo "building node installer ..."
architects=("amd64")
diff --git a/EdgeAPI/internal/clickhouse/httpdns_access_logs_store.go b/EdgeAPI/internal/clickhouse/httpdns_access_logs_store.go
index a794c5c..3e73d61 100644
--- a/EdgeAPI/internal/clickhouse/httpdns_access_logs_store.go
+++ b/EdgeAPI/internal/clickhouse/httpdns_access_logs_store.go
@@ -47,6 +47,33 @@ type HTTPDNSAccessLogListFilter struct {
Size int64
}
+type HTTPDNSAccessLogHourlyStat struct {
+ Hour string
+ CountRequests int64
+}
+
+type HTTPDNSAccessLogDailyStat struct {
+ Day string
+ CountRequests int64
+}
+
+type HTTPDNSAccessLogTopAppStat struct {
+ AppId string
+ AppName string
+ CountRequests int64
+}
+
+type HTTPDNSAccessLogTopDomainStat struct {
+ Domain string
+ CountRequests int64
+}
+
+type HTTPDNSAccessLogTopNodeStat struct {
+ ClusterId uint32
+ NodeId uint32
+ CountRequests int64
+}
+
type HTTPDNSAccessLogsStore struct {
client *Client
}
@@ -176,6 +203,155 @@ func (s *HTTPDNSAccessLogsStore) List(ctx context.Context, f HTTPDNSAccessLogLis
return result, nil
}
+func (s *HTTPDNSAccessLogsStore) FindHourlyStats(ctx context.Context, hourFrom string, hourTo string) ([]*HTTPDNSAccessLogHourlyStat, error) {
+ if !s.client.IsConfigured() {
+ return nil, fmt.Errorf("clickhouse: not configured")
+ }
+
+ query := fmt.Sprintf(
+ "SELECT formatDateTime(toDateTime(created_at), '%%Y%%m%%d%%H') AS hour, count() AS count_requests FROM %s WHERE formatDateTime(toDateTime(created_at), '%%Y%%m%%d%%H') BETWEEN '%s' AND '%s' GROUP BY hour ORDER BY hour ASC",
+ s.tableName(),
+ escapeString(hourFrom),
+ escapeString(hourTo),
+ )
+
+ rows := []map[string]interface{}{}
+ if err := s.client.Query(ctx, query, &rows); err != nil {
+ return nil, err
+ }
+
+ result := make([]*HTTPDNSAccessLogHourlyStat, 0, len(rows))
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogHourlyStat{
+ Hour: toString(row["hour"]),
+ CountRequests: toInt64(row["count_requests"]),
+ })
+ }
+ return result, nil
+}
+
+func (s *HTTPDNSAccessLogsStore) FindDailyStats(ctx context.Context, dayFrom string, dayTo string) ([]*HTTPDNSAccessLogDailyStat, error) {
+ if !s.client.IsConfigured() {
+ return nil, fmt.Errorf("clickhouse: not configured")
+ }
+
+ query := fmt.Sprintf(
+ "SELECT day, count() AS count_requests FROM %s WHERE day BETWEEN '%s' AND '%s' GROUP BY day ORDER BY day ASC",
+ s.tableName(),
+ escapeString(dayFrom),
+ escapeString(dayTo),
+ )
+
+ rows := []map[string]interface{}{}
+ if err := s.client.Query(ctx, query, &rows); err != nil {
+ return nil, err
+ }
+
+ result := make([]*HTTPDNSAccessLogDailyStat, 0, len(rows))
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogDailyStat{
+ Day: toString(row["day"]),
+ CountRequests: toInt64(row["count_requests"]),
+ })
+ }
+ return result, nil
+}
+
+func (s *HTTPDNSAccessLogsStore) ListTopApps(ctx context.Context, dayFrom string, dayTo string, limit int64) ([]*HTTPDNSAccessLogTopAppStat, error) {
+ if !s.client.IsConfigured() {
+ return nil, fmt.Errorf("clickhouse: not configured")
+ }
+ if limit <= 0 {
+ limit = 10
+ }
+
+ query := fmt.Sprintf(
+ "SELECT app_id, max(app_name) AS app_name, count() AS count_requests FROM %s WHERE day BETWEEN '%s' AND '%s' GROUP BY app_id ORDER BY count_requests DESC LIMIT %d",
+ s.tableName(),
+ escapeString(dayFrom),
+ escapeString(dayTo),
+ limit,
+ )
+
+ rows := []map[string]interface{}{}
+ if err := s.client.Query(ctx, query, &rows); err != nil {
+ return nil, err
+ }
+
+ result := make([]*HTTPDNSAccessLogTopAppStat, 0, len(rows))
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogTopAppStat{
+ AppId: toString(row["app_id"]),
+ AppName: toString(row["app_name"]),
+ CountRequests: toInt64(row["count_requests"]),
+ })
+ }
+ return result, nil
+}
+
+func (s *HTTPDNSAccessLogsStore) ListTopDomains(ctx context.Context, dayFrom string, dayTo string, limit int64) ([]*HTTPDNSAccessLogTopDomainStat, error) {
+ if !s.client.IsConfigured() {
+ return nil, fmt.Errorf("clickhouse: not configured")
+ }
+ if limit <= 0 {
+ limit = 10
+ }
+
+ query := fmt.Sprintf(
+ "SELECT domain, count() AS count_requests FROM %s WHERE day BETWEEN '%s' AND '%s' AND domain != '' GROUP BY domain ORDER BY count_requests DESC LIMIT %d",
+ s.tableName(),
+ escapeString(dayFrom),
+ escapeString(dayTo),
+ limit,
+ )
+
+ rows := []map[string]interface{}{}
+ if err := s.client.Query(ctx, query, &rows); err != nil {
+ return nil, err
+ }
+
+ result := make([]*HTTPDNSAccessLogTopDomainStat, 0, len(rows))
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogTopDomainStat{
+ Domain: toString(row["domain"]),
+ CountRequests: toInt64(row["count_requests"]),
+ })
+ }
+ return result, nil
+}
+
+func (s *HTTPDNSAccessLogsStore) ListTopNodes(ctx context.Context, dayFrom string, dayTo string, limit int64) ([]*HTTPDNSAccessLogTopNodeStat, error) {
+ if !s.client.IsConfigured() {
+ return nil, fmt.Errorf("clickhouse: not configured")
+ }
+ if limit <= 0 {
+ limit = 10
+ }
+
+ query := fmt.Sprintf(
+ "SELECT min(cluster_id) AS cluster_id, node_id, count() AS count_requests FROM %s WHERE day BETWEEN '%s' AND '%s' GROUP BY node_id ORDER BY count_requests DESC LIMIT %d",
+ s.tableName(),
+ escapeString(dayFrom),
+ escapeString(dayTo),
+ limit,
+ )
+
+ rows := []map[string]interface{}{}
+ if err := s.client.Query(ctx, query, &rows); err != nil {
+ return nil, err
+ }
+
+ result := make([]*HTTPDNSAccessLogTopNodeStat, 0, len(rows))
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogTopNodeStat{
+ ClusterId: uint32(toInt64(row["cluster_id"])),
+ NodeId: uint32(toInt64(row["node_id"])),
+ CountRequests: toInt64(row["count_requests"]),
+ })
+ }
+ return result, nil
+}
+
func HTTPDNSRowToPB(row *HTTPDNSAccessLogRow) *pb.HTTPDNSAccessLog {
if row == nil {
return nil
diff --git a/EdgeAPI/internal/const/const.go b/EdgeAPI/internal/const/const.go
index c3b3d66..daab8e9 100644
--- a/EdgeAPI/internal/const/const.go
+++ b/EdgeAPI/internal/const/const.go
@@ -1,7 +1,7 @@
package teaconst
const (
- Version = "1.4.9" //1.3.9
+ Version = "1.5.0" //1.3.9
ProductName = "Edge API"
ProcessName = "edge-api"
@@ -17,6 +17,6 @@ const (
// 其他节点版本号,用来检测是否有需要升级的节点
- NodeVersion = "1.4.9" //1.3.8.2
+ NodeVersion = "1.5.0" //1.3.8.2
)
diff --git a/EdgeAPI/internal/const/const_plus.go b/EdgeAPI/internal/const/const_plus.go
index 5b679bd..2bb0568 100644
--- a/EdgeAPI/internal/const/const_plus.go
+++ b/EdgeAPI/internal/const/const_plus.go
@@ -4,9 +4,9 @@
package teaconst
const (
- DNSNodeVersion = "1.4.9" //1.3.8.2
- UserNodeVersion = "1.4.9" //1.3.8.2
- ReportNodeVersion = "0.1.5"
+ DNSNodeVersion = "1.5.0" //1.3.8.2
+ UserNodeVersion = "1.5.0" //1.3.8.2
+ ReportNodeVersion = "1.5.0"
DefaultMaxNodes int32 = 50
)
diff --git a/EdgeAPI/internal/db/models/httpdns_access_log_dao_stat.go b/EdgeAPI/internal/db/models/httpdns_access_log_dao_stat.go
new file mode 100644
index 0000000..fc17dcc
--- /dev/null
+++ b/EdgeAPI/internal/db/models/httpdns_access_log_dao_stat.go
@@ -0,0 +1,138 @@
+package models
+
+import (
+ "github.com/iwind/TeaGo/dbs"
+)
+
+type HTTPDNSAccessLogHourlyStat struct {
+ Hour string `field:"hour"`
+ CountRequests int64 `field:"countRequests"`
+}
+
+type HTTPDNSAccessLogDailyStat struct {
+ Day string `field:"day"`
+ CountRequests int64 `field:"countRequests"`
+}
+
+type HTTPDNSAccessLogTopAppStat struct {
+ AppId string `field:"appId"`
+ AppName string `field:"appName"`
+ CountRequests int64 `field:"countRequests"`
+}
+
+type HTTPDNSAccessLogTopDomainStat struct {
+ Domain string `field:"domain"`
+ CountRequests int64 `field:"countRequests"`
+}
+
+type HTTPDNSAccessLogTopNodeStat struct {
+ ClusterId uint32 `field:"clusterId"`
+ NodeId uint32 `field:"nodeId"`
+ CountRequests int64 `field:"countRequests"`
+}
+
+func (this *HTTPDNSAccessLogDAO) FindHourlyStats(tx *dbs.Tx, hourFrom string, hourTo string) (result []*HTTPDNSAccessLogHourlyStat, err error) {
+ rows, _, err := this.Query(tx).
+ Result("CONCAT(day, LPAD(HOUR(FROM_UNIXTIME(createdAt)),2,'0')) AS hour", "COUNT(*) AS countRequests").
+ Where("CONCAT(day, LPAD(HOUR(FROM_UNIXTIME(createdAt)),2,'0')) BETWEEN :hourFrom AND :hourTo").
+ Param("hourFrom", hourFrom).
+ Param("hourTo", hourTo).
+ Group("hour").
+ FindOnes()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogHourlyStat{
+ Hour: row.GetString("hour"),
+ CountRequests: row.GetInt64("countRequests"),
+ })
+ }
+ return
+}
+
+func (this *HTTPDNSAccessLogDAO) FindDailyStats(tx *dbs.Tx, dayFrom string, dayTo string) (result []*HTTPDNSAccessLogDailyStat, err error) {
+ rows, _, err := this.Query(tx).
+ Result("day", "COUNT(*) AS countRequests").
+ Between("day", dayFrom, dayTo).
+ Group("day").
+ FindOnes()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogDailyStat{
+ Day: row.GetString("day"),
+ CountRequests: row.GetInt64("countRequests"),
+ })
+ }
+ return
+}
+
+func (this *HTTPDNSAccessLogDAO) ListTopApps(tx *dbs.Tx, dayFrom string, dayTo string, limit int64) (result []*HTTPDNSAccessLogTopAppStat, err error) {
+ rows, _, err := this.Query(tx).
+ Result("appId", "MAX(appName) AS appName", "COUNT(*) AS countRequests").
+ Between("day", dayFrom, dayTo).
+ Group("appId").
+ Desc("countRequests").
+ Limit(limit).
+ FindOnes()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogTopAppStat{
+ AppId: row.GetString("appId"),
+ AppName: row.GetString("appName"),
+ CountRequests: row.GetInt64("countRequests"),
+ })
+ }
+ return
+}
+
+func (this *HTTPDNSAccessLogDAO) ListTopDomains(tx *dbs.Tx, dayFrom string, dayTo string, limit int64) (result []*HTTPDNSAccessLogTopDomainStat, err error) {
+ rows, _, err := this.Query(tx).
+ Result("domain", "COUNT(*) AS countRequests").
+ Between("day", dayFrom, dayTo).
+ Where("domain != ''").
+ Group("domain").
+ Desc("countRequests").
+ Limit(limit).
+ FindOnes()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogTopDomainStat{
+ Domain: row.GetString("domain"),
+ CountRequests: row.GetInt64("countRequests"),
+ })
+ }
+ return
+}
+
+func (this *HTTPDNSAccessLogDAO) ListTopNodes(tx *dbs.Tx, dayFrom string, dayTo string, limit int64) (result []*HTTPDNSAccessLogTopNodeStat, err error) {
+ rows, _, err := this.Query(tx).
+ Result("MIN(clusterId) AS clusterId", "nodeId", "COUNT(*) AS countRequests").
+ Between("day", dayFrom, dayTo).
+ Group("nodeId").
+ Desc("countRequests").
+ Limit(limit).
+ FindOnes()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, row := range rows {
+ result = append(result, &HTTPDNSAccessLogTopNodeStat{
+ ClusterId: row.GetUint32("clusterId"),
+ NodeId: row.GetUint32("nodeId"),
+ CountRequests: row.GetInt64("countRequests"),
+ })
+ }
+ return
+}
diff --git a/EdgeAPI/internal/db/models/httpdns_domain_dao.go b/EdgeAPI/internal/db/models/httpdns_domain_dao.go
index 2330869..b4133ea 100644
--- a/EdgeAPI/internal/db/models/httpdns_domain_dao.go
+++ b/EdgeAPI/internal/db/models/httpdns_domain_dao.go
@@ -113,3 +113,11 @@ func (this *HTTPDNSDomainDAO) ListEnabledDomainsWithAppId(tx *dbs.Tx, appDbId in
_, err = query.Slice(&result).FindAll()
return
}
+
+func (this *HTTPDNSDomainDAO) CountEnabledDomains(tx *dbs.Tx, appDbId int64) (int64, error) {
+ query := this.Query(tx).State(HTTPDNSDomainStateEnabled)
+ if appDbId > 0 {
+ query = query.Attr("appId", appDbId)
+ }
+ return query.Count()
+}
diff --git a/EdgeAPI/internal/db/models/node_value_dao.go b/EdgeAPI/internal/db/models/node_value_dao.go
index c9f523d..7422376 100644
--- a/EdgeAPI/internal/db/models/node_value_dao.go
+++ b/EdgeAPI/internal/db/models/node_value_dao.go
@@ -221,6 +221,41 @@ func (this *NodeValueDAO) ListValuesForNSNodes(tx *dbs.Tx, item string, key stri
return
}
+// ListValuesForHTTPDNSNodes 列出HTTPDNS节点相关的平均数据
+func (this *NodeValueDAO) ListValuesForHTTPDNSNodes(tx *dbs.Tx, item string, key string, timeRange nodeconfigs.NodeValueRange) (result []*NodeValue, err error) {
+ query := this.Query(tx).
+ Attr("role", "httpdns").
+ Attr("item", item).
+ Result("AVG(JSON_EXTRACT(value, '$." + key + "')) AS value, MIN(createdAt) AS createdAt")
+
+ switch timeRange {
+ // TODO 支持更多的时间范围
+ case nodeconfigs.NodeValueRangeMinute:
+ fromMinute := timeutil.FormatTime("YmdHi", time.Now().Unix()-3600) // 一个小时之前的
+ query.Gte("minute", fromMinute)
+ query.Result("minute")
+ query.Group("minute")
+ default:
+ err = errors.New("invalid 'range' value: '" + timeRange + "'")
+ return
+ }
+
+ _, err = query.Slice(&result).
+ FindAll()
+
+ if err != nil {
+ return nil, err
+ }
+
+ for _, nodeValue := range result {
+ nodeValue.Value, _ = json.Marshal(maps.Map{
+ key: types.Float32(string(nodeValue.Value)),
+ })
+ }
+
+ return
+}
+
// SumAllNodeValues 计算所有节点的某项参数值
func (this *NodeValueDAO) SumAllNodeValues(tx *dbs.Tx, role string, item nodeconfigs.NodeValueItem, param string, duration int32, durationUnit nodeconfigs.NodeValueDurationUnit) (total float64, avg float64, max float64, err error) {
if duration <= 0 {
diff --git a/EdgeAPI/internal/installers/fluent_bit.go b/EdgeAPI/internal/installers/fluent_bit.go
deleted file mode 100644
index 9357b1d..0000000
--- a/EdgeAPI/internal/installers/fluent_bit.go
+++ /dev/null
@@ -1,889 +0,0 @@
-package installers
-
-import (
- "crypto/sha256"
- "encoding/json"
- "errors"
- "fmt"
- "net/url"
- "os"
- slashpath "path"
- "path/filepath"
- "sort"
- "strconv"
- "strings"
- "time"
-
- teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
- "github.com/TeaOSLab/EdgeAPI/internal/db/models"
- "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
- "github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
- "github.com/iwind/TeaGo/Tea"
-)
-
-const (
- fluentBitConfigDir = "/etc/fluent-bit"
- fluentBitStorageDir = "/var/lib/fluent-bit/storage"
- fluentBitMainConfigFile = "/etc/fluent-bit/fluent-bit.conf"
- fluentBitParsersFile = "/etc/fluent-bit/parsers.conf"
- fluentBitManagedMetaFile = "/etc/fluent-bit/.edge-managed.json"
- fluentBitManagedEnvFile = "/etc/fluent-bit/.edge-managed.env"
- fluentBitDropInDir = "/etc/systemd/system/fluent-bit.service.d"
- fluentBitDropInFile = "/etc/systemd/system/fluent-bit.service.d/edge-managed.conf"
- fluentBitServiceName = "fluent-bit"
- fluentBitDefaultBinPath = "/opt/fluent-bit/bin/fluent-bit"
- fluentBitLocalPackagesRoot = "packages"
- fluentBitHTTPPathPattern = "/var/log/edge/edge-node/*.log"
- fluentBitDNSPathPattern = "/var/log/edge/edge-dns/*.log"
- fluentBitHTTPDNSPathPattern = "/var/log/edge/edge-httpdns/*.log"
- fluentBitManagedMarker = "managed-by-edgeapi"
- fluentBitRoleNode = "node"
- fluentBitRoleDNS = "dns"
- fluentBitRoleHTTPDNS = "httpdns"
-)
-
-var errFluentBitLocalPackageNotFound = errors.New("fluent-bit local package not found")
-
-var fluentBitPackageFileMapping = map[string]string{
- "ubuntu22.04-amd64": "fluent-bit_4.2.2_amd64.deb",
- "ubuntu22.04-arm64": "fluent-bit_4.2.2_arm64.deb",
- "amzn2023-amd64": "fluent-bit-4.2.2-1.x86_64.rpm",
- "amzn2023-arm64": "fluent-bit-4.2.2-1.aarch64.rpm",
-}
-
-type fluentBitManagedMeta struct {
- Roles []string `json:"roles"`
- Hash string `json:"hash"`
- UpdatedAt int64 `json:"updatedAt"`
- SourceVersion string `json:"sourceVersion"`
-}
-
-type fluentBitDesiredConfig struct {
- Roles []string
- ClickHouse *systemconfigs.ClickHouseSetting
- HTTPPathPattern string
- DNSPathPattern string
- HTTPDNSPathPattern string
-}
-
-// SetupFluentBit 安装并托管 Fluent Bit 配置(离线包 + 平台渲染配置)。
-func (this *BaseInstaller) SetupFluentBit(role nodeconfigs.NodeRole) error {
- if this.client == nil {
- return errors.New("ssh client is nil")
- }
-
- uname := this.uname()
- if !strings.Contains(uname, "Linux") {
- return nil
- }
-
- tempDir := strings.TrimRight(this.client.UserHome(), "/") + "/.edge-fluent-bit"
- _, _, _ = this.client.Exec("mkdir -p " + shQuote(tempDir))
- defer func() {
- _, _, _ = this.client.Exec("rm -rf " + shQuote(tempDir))
- }()
-
- if err := this.ensureFluentBitInstalled(tempDir); err != nil {
- return err
- }
-
- _, stderr, err := this.client.Exec("mkdir -p " + shQuote(fluentBitConfigDir) + " " + shQuote(fluentBitStorageDir))
- if err != nil {
- return fmt.Errorf("prepare fluent-bit directories failed: %w, stderr: %s", err, stderr)
- }
-
- parserContent, err := this.readLocalParsersContent()
- if err != nil {
- return err
- }
-
- existingMeta, err := this.readManagedMeta()
- if err != nil {
- return err
- }
-
- mergedRoles, err := mergeManagedRoles(existingMeta, role)
- if err != nil {
- return err
- }
-
- desiredConfig, err := this.buildDesiredFluentBitConfig(mergedRoles)
- if err != nil {
- return err
- }
-
- configChanged, err := this.applyManagedConfig(tempDir, desiredConfig, parserContent, existingMeta)
- if err != nil {
- return err
- }
-
- binPath, err := this.lookupFluentBitBinPath()
- if err != nil {
- return err
- }
-
- if err := this.ensureFluentBitService(tempDir, binPath, configChanged); err != nil {
- return err
- }
-
- return nil
-}
-
-func (this *BaseInstaller) ensureFluentBitInstalled(tempDir string) error {
- binPath, _ := this.lookupFluentBitBinPath()
- if binPath != "" {
- return nil
- }
-
- platformKey, packageName, arch, err := this.detectRemotePlatformAndPackage()
- if err != nil {
- return fmt.Errorf("detect fluent-bit platform failed: %w", err)
- }
-
- if err := this.installFluentBitFromLocalPackage(tempDir, arch, packageName); err != nil {
- if errors.Is(err, errFluentBitLocalPackageNotFound) {
- expectedPath := filepath.Join("deploy", "fluent-bit", fluentBitLocalPackagesRoot, "linux-"+arch, packageName)
- return fmt.Errorf("install fluent-bit failed: local package missing for platform '%s', expected '%s'", platformKey, expectedPath)
- }
- return fmt.Errorf("install fluent-bit from local package failed: %w", err)
- }
-
- binPath, err = this.lookupFluentBitBinPath()
- if err != nil {
- return err
- }
- if binPath == "" {
- return errors.New("fluent-bit binary not found after local package install")
- }
-
- _, stderr, err := this.client.Exec(binPath + " --version")
- if err != nil {
- return fmt.Errorf("verify fluent-bit version failed: %w, stderr: %s", err, stderr)
- }
-
- return nil
-}
-
-func (this *BaseInstaller) installFluentBitFromLocalPackage(tempDir string, arch string, packageName string) error {
- packageDir := filepath.Join(Tea.Root, "deploy", "fluent-bit", fluentBitLocalPackagesRoot, "linux-"+arch)
- localPackagePath := filepath.Join(packageDir, packageName)
- if _, err := os.Stat(localPackagePath); err != nil {
- if os.IsNotExist(err) {
- return errFluentBitLocalPackageNotFound
- }
- return fmt.Errorf("check local package failed: %w", err)
- }
-
- remotePackagePath := tempDir + "/" + filepath.Base(localPackagePath)
- if err := this.client.Copy(localPackagePath, remotePackagePath, 0644); err != nil {
- return fmt.Errorf("upload local package failed: %w", err)
- }
-
- var installCmd string
- lowerName := strings.ToLower(localPackagePath)
- switch {
- case strings.HasSuffix(lowerName, ".deb"):
- installCmd = "dpkg -i " + shQuote(remotePackagePath)
- case strings.HasSuffix(lowerName, ".rpm"):
- installCmd = "rpm -Uvh --force " + shQuote(remotePackagePath) + " || rpm -ivh --force " + shQuote(remotePackagePath)
- case strings.HasSuffix(lowerName, ".tar.gz") || strings.HasSuffix(lowerName, ".tgz"):
- extractDir := tempDir + "/extract"
- installCmd = "rm -rf " + shQuote(extractDir) + "; mkdir -p " + shQuote(extractDir) + "; tar -xzf " + shQuote(remotePackagePath) + " -C " + shQuote(extractDir) + "; " +
- "bin=$(find " + shQuote(extractDir) + " -type f -name fluent-bit | head -n 1); " +
- "if [ -z \"$bin\" ]; then exit 3; fi; " +
- "mkdir -p /opt/fluent-bit/bin /usr/local/bin; " +
- "install -m 0755 \"$bin\" /opt/fluent-bit/bin/fluent-bit; " +
- "ln -sf /opt/fluent-bit/bin/fluent-bit /usr/local/bin/fluent-bit"
- default:
- return fmt.Errorf("unsupported local package format: %s", packageName)
- }
-
- _, stderr, err := this.client.Exec(installCmd)
- if err != nil {
- return fmt.Errorf("install fluent-bit local package '%s' failed: %w, stderr: %s", filepath.Base(localPackagePath), err, stderr)
- }
-
- return nil
-}
-
-func (this *BaseInstaller) detectRemotePlatformAndPackage() (platformKey string, packageName string, arch string, err error) {
- arch, err = this.detectRemoteLinuxArch()
- if err != nil {
- return "", "", "", err
- }
-
- releaseData, stderr, err := this.client.Exec("cat /etc/os-release")
- if err != nil {
- return "", "", "", fmt.Errorf("read /etc/os-release failed: %w, stderr: %s", err, stderr)
- }
- if strings.TrimSpace(releaseData) == "" {
- return "", "", "", errors.New("/etc/os-release is empty")
- }
-
- releaseMap := parseOSRelease(releaseData)
- id := strings.ToLower(strings.TrimSpace(releaseMap["ID"]))
- versionID := strings.TrimSpace(releaseMap["VERSION_ID"])
-
- var distro string
- switch {
- case id == "ubuntu" && strings.HasPrefix(versionID, "22.04"):
- distro = "ubuntu22.04"
- case id == "amzn" && strings.HasPrefix(versionID, "2023"):
- distro = "amzn2023"
- default:
- return "", "", "", fmt.Errorf("unsupported linux platform id='%s' version='%s'", id, versionID)
- }
-
- platformKey = distro + "-" + arch
- packageName, ok := fluentBitPackageFileMapping[platformKey]
- if !ok {
- return "", "", "", fmt.Errorf("no local package mapping for platform '%s'", platformKey)
- }
- return platformKey, packageName, arch, nil
-}
-
-func parseOSRelease(content string) map[string]string {
- result := map[string]string{}
- lines := strings.Split(content, "\n")
- for _, line := range lines {
- line = strings.TrimSpace(line)
- if line == "" || strings.HasPrefix(line, "#") || !strings.Contains(line, "=") {
- continue
- }
- parts := strings.SplitN(line, "=", 2)
- key := strings.TrimSpace(parts[0])
- value := strings.TrimSpace(parts[1])
- value = strings.Trim(value, "\"")
- result[key] = value
- }
- return result
-}
-
-func (this *BaseInstaller) detectRemoteLinuxArch() (string, error) {
- stdout, stderr, err := this.client.Exec("uname -m")
- if err != nil {
- return "", fmt.Errorf("detect remote arch failed: %w, stderr: %s", err, stderr)
- }
-
- arch := strings.ToLower(strings.TrimSpace(stdout))
- switch arch {
- case "x86_64", "amd64":
- return "amd64", nil
- case "aarch64", "arm64":
- return "arm64", nil
- default:
- return arch, nil
- }
-}
-
-func (this *BaseInstaller) lookupFluentBitBinPath() (string, error) {
- stdout, stderr, err := this.client.Exec("if command -v fluent-bit >/dev/null 2>&1; then command -v fluent-bit; elif [ -x " + fluentBitDefaultBinPath + " ]; then echo " + fluentBitDefaultBinPath + "; fi")
- if err != nil {
- return "", fmt.Errorf("lookup fluent-bit binary failed: %w, stderr: %s", err, stderr)
- }
- return strings.TrimSpace(stdout), nil
-}
-
-func (this *BaseInstaller) readLocalParsersContent() (string, error) {
- parsersPath := filepath.Join(Tea.Root, "deploy", "fluent-bit", "parsers.conf")
- data, err := os.ReadFile(parsersPath)
- if err != nil {
- return "", fmt.Errorf("read local parsers config failed: %w", err)
- }
- return string(data), nil
-}
-
-func (this *BaseInstaller) readManagedMeta() (*fluentBitManagedMeta, error) {
- exists, err := this.remoteFileExists(fluentBitManagedMetaFile)
- if err != nil {
- return nil, err
- }
- if !exists {
- return nil, nil
- }
-
- content, stderr, err := this.client.Exec("cat " + shQuote(fluentBitManagedMetaFile))
- if err != nil {
- return nil, fmt.Errorf("read fluent-bit managed metadata failed: %w, stderr: %s", err, stderr)
- }
- if strings.TrimSpace(content) == "" {
- return nil, nil
- }
-
- meta := &fluentBitManagedMeta{}
- if err := json.Unmarshal([]byte(content), meta); err != nil {
- return nil, fmt.Errorf("decode fluent-bit managed metadata failed: %w", err)
- }
- meta.Roles = normalizeRoles(meta.Roles)
- return meta, nil
-}
-
-func mergeManagedRoles(meta *fluentBitManagedMeta, role nodeconfigs.NodeRole) ([]string, error) {
- roleName, err := mapNodeRole(role)
- if err != nil {
- return nil, err
- }
-
- roleSet := map[string]struct{}{}
- if meta != nil {
- for _, r := range normalizeRoles(meta.Roles) {
- roleSet[r] = struct{}{}
- }
- }
- roleSet[roleName] = struct{}{}
-
- roles := make([]string, 0, len(roleSet))
- for r := range roleSet {
- roles = append(roles, r)
- }
- sort.Strings(roles)
- return roles, nil
-}
-
-func mapNodeRole(role nodeconfigs.NodeRole) (string, error) {
- switch role {
- case nodeconfigs.NodeRoleNode:
- return fluentBitRoleNode, nil
- case nodeconfigs.NodeRoleDNS:
- return fluentBitRoleDNS, nil
- case nodeconfigs.NodeRoleHTTPDNS:
- return fluentBitRoleHTTPDNS, nil
- default:
- return "", fmt.Errorf("unsupported fluent-bit role '%s'", role)
- }
-}
-
-func normalizeRoles(rawRoles []string) []string {
- roleSet := map[string]struct{}{}
- for _, role := range rawRoles {
- role = strings.ToLower(strings.TrimSpace(role))
- if role != fluentBitRoleNode && role != fluentBitRoleDNS && role != fluentBitRoleHTTPDNS {
- continue
- }
- roleSet[role] = struct{}{}
- }
-
- roles := make([]string, 0, len(roleSet))
- for role := range roleSet {
- roles = append(roles, role)
- }
- sort.Strings(roles)
- return roles
-}
-
-func hasRole(roles []string, role string) bool {
- for _, one := range roles {
- if one == role {
- return true
- }
- }
- return false
-}
-
-func (this *BaseInstaller) buildDesiredFluentBitConfig(roles []string) (*fluentBitDesiredConfig, error) {
- if len(roles) == 0 {
- return nil, errors.New("fluent-bit roles should not be empty")
- }
-
- ch, err := models.SharedSysSettingDAO.ReadClickHouseConfig(nil)
- if err != nil {
- return nil, fmt.Errorf("read clickhouse setting failed: %w", err)
- }
- if ch == nil {
- ch = &systemconfigs.ClickHouseSetting{}
- }
- if strings.TrimSpace(ch.Host) == "" {
- ch.Host = "127.0.0.1"
- }
-
- ch.Scheme = strings.ToLower(strings.TrimSpace(ch.Scheme))
- if ch.Scheme == "" {
- ch.Scheme = "https"
- }
- if ch.Scheme != "http" && ch.Scheme != "https" {
- return nil, fmt.Errorf("unsupported clickhouse scheme '%s'", ch.Scheme)
- }
-
- if ch.Port <= 0 {
- if ch.Scheme == "https" {
- ch.Port = 8443
- } else {
- ch.Port = 8443
- }
- }
- if strings.TrimSpace(ch.Database) == "" {
- ch.Database = "default"
- }
- if strings.TrimSpace(ch.User) == "" {
- ch.User = "default"
- }
- // 当前平台策略:后台固定跳过 ClickHouse TLS 证书校验,不暴露 ServerName 配置。
- ch.TLSSkipVerify = true
- ch.TLSServerName = ""
-
- httpPathPattern := fluentBitHTTPPathPattern
- dnsPathPattern := fluentBitDNSPathPattern
- httpdnsPathPattern := fluentBitHTTPDNSPathPattern
- publicPolicyPath, err := this.readPublicAccessLogPolicyPath()
- if err != nil {
- return nil, err
- }
- policyDir := dirFromPolicyPath(publicPolicyPath)
- if policyDir != "" {
- pattern := strings.TrimRight(policyDir, "/") + "/*.log"
- httpPathPattern = pattern
- dnsPathPattern = pattern
- httpdnsPathPattern = pattern
- }
-
- return &fluentBitDesiredConfig{
- Roles: normalizeRoles(roles),
- ClickHouse: ch,
- HTTPPathPattern: httpPathPattern,
- DNSPathPattern: dnsPathPattern,
- HTTPDNSPathPattern: httpdnsPathPattern,
- }, nil
-}
-
-func (this *BaseInstaller) readPublicAccessLogPolicyPath() (string, error) {
- policyId, err := models.SharedHTTPAccessLogPolicyDAO.FindCurrentPublicPolicyId(nil)
- if err != nil {
- return "", fmt.Errorf("find current public access log policy failed: %w", err)
- }
- if policyId <= 0 {
- return "", nil
- }
-
- policy, err := models.SharedHTTPAccessLogPolicyDAO.FindEnabledHTTPAccessLogPolicy(nil, policyId)
- if err != nil {
- return "", fmt.Errorf("read public access log policy failed: %w", err)
- }
- if policy == nil {
- return "", nil
- }
-
- return strings.TrimSpace(models.ParseHTTPAccessLogPolicyFilePath(policy)), nil
-}
-
-func dirFromPolicyPath(policyPath string) string {
- pathValue := strings.TrimSpace(policyPath)
- if pathValue == "" {
- return ""
- }
- pathValue = strings.ReplaceAll(pathValue, "\\", "/")
- dir := slashpath.Dir(pathValue)
- if dir == "." {
- return ""
- }
- return strings.TrimRight(dir, "/")
-}
-
-func (this *BaseInstaller) applyManagedConfig(tempDir string, desired *fluentBitDesiredConfig, parserContent string, existingMeta *fluentBitManagedMeta) (bool, error) {
- mainExists, err := this.remoteFileExists(fluentBitMainConfigFile)
- if err != nil {
- return false, err
- }
-
- if mainExists && existingMeta == nil {
- containsMarker, err := this.remoteFileContains(fluentBitMainConfigFile, fluentBitManagedMarker)
- if err != nil {
- return false, err
- }
- if !containsMarker {
- // Adopt unmanaged config by backing it up and replacing with managed config below.
- }
- }
-
- configContent, err := renderManagedConfig(desired)
- if err != nil {
- return false, err
- }
- envContent := renderManagedEnv(desired.ClickHouse)
- metaContent, newMeta, err := renderManagedMeta(desired, configContent, parserContent, envContent)
- if err != nil {
- return false, err
- }
-
- requiredFiles := []string{fluentBitMainConfigFile, fluentBitParsersFile, fluentBitManagedEnvFile, fluentBitManagedMetaFile}
- if existingMeta != nil && existingMeta.Hash == newMeta.Hash {
- allExists := true
- for _, file := range requiredFiles {
- exists, err := this.remoteFileExists(file)
- if err != nil {
- return false, err
- }
- if !exists {
- allExists = false
- break
- }
- }
- if allExists {
- return false, nil
- }
- }
-
- if mainExists {
- backup := fluentBitMainConfigFile + ".bak." + strconv.FormatInt(time.Now().Unix(), 10)
- _, stderr, err := this.client.Exec("cp -f " + shQuote(fluentBitMainConfigFile) + " " + shQuote(backup))
- if err != nil {
- return false, fmt.Errorf("backup existing fluent-bit config failed: %w, stderr: %s", err, stderr)
- }
- }
-
- if err := this.writeRemoteFileByTemp(tempDir, fluentBitMainConfigFile, configContent, 0644); err != nil {
- return false, err
- }
- if err := this.writeRemoteFileByTemp(tempDir, fluentBitParsersFile, parserContent, 0644); err != nil {
- return false, err
- }
- if err := this.writeRemoteFileByTemp(tempDir, fluentBitManagedEnvFile, envContent, 0600); err != nil {
- return false, err
- }
- if err := this.writeRemoteFileByTemp(tempDir, fluentBitManagedMetaFile, metaContent, 0644); err != nil {
- return false, err
- }
-
- return true, nil
-}
-
-func renderManagedConfig(desired *fluentBitDesiredConfig) (string, error) {
- if desired == nil || desired.ClickHouse == nil {
- return "", errors.New("invalid fluent-bit desired config")
- }
-
- scheme := strings.ToLower(strings.TrimSpace(desired.ClickHouse.Scheme))
- if scheme == "" {
- scheme = "http"
- }
- if scheme != "http" && scheme != "https" {
- return "", fmt.Errorf("unsupported clickhouse scheme '%s'", desired.ClickHouse.Scheme)
- }
- useTLS := scheme == "https"
-
- insertHTTP := url.QueryEscape(fmt.Sprintf("INSERT INTO %s.logs_ingest FORMAT JSONEachRow", desired.ClickHouse.Database))
- insertDNS := url.QueryEscape(fmt.Sprintf("INSERT INTO %s.dns_logs_ingest FORMAT JSONEachRow", desired.ClickHouse.Database))
- insertHTTPDNS := url.QueryEscape(fmt.Sprintf("INSERT INTO %s.httpdns_access_logs_ingest FORMAT JSONEachRow", desired.ClickHouse.Database))
-
- lines := []string{
- "# " + fluentBitManagedMarker,
- "[SERVICE]",
- " Flush 1",
- " Log_Level info",
- " Parsers_File " + fluentBitParsersFile,
- " storage.path " + fluentBitStorageDir,
- " storage.sync normal",
- " storage.checksum off",
- " storage.backlog.mem_limit 512MB",
- "",
- }
-
- if hasRole(desired.Roles, fluentBitRoleNode) {
- lines = append(lines,
- "[INPUT]",
- " Name tail",
- " Path "+desired.HTTPPathPattern,
- " Tag app.http.logs",
- " Parser json",
- " Refresh_Interval 2",
- " Read_from_Head false",
- " DB /var/lib/fluent-bit/http-logs.db",
- " storage.type filesystem",
- " Mem_Buf_Limit 256MB",
- " Skip_Long_Lines On",
- "",
- )
- }
-
- if hasRole(desired.Roles, fluentBitRoleDNS) {
- lines = append(lines,
- "[INPUT]",
- " Name tail",
- " Path "+desired.DNSPathPattern,
- " Tag app.dns.logs",
- " Parser json",
- " Refresh_Interval 2",
- " Read_from_Head false",
- " DB /var/lib/fluent-bit/dns-logs.db",
- " storage.type filesystem",
- " Mem_Buf_Limit 256MB",
- " Skip_Long_Lines On",
- "",
- )
- }
-
- if hasRole(desired.Roles, fluentBitRoleHTTPDNS) {
- lines = append(lines,
- "[INPUT]",
- " Name tail",
- " Path "+desired.HTTPDNSPathPattern,
- " Tag app.httpdns.logs",
- " Parser json",
- " Refresh_Interval 2",
- " Read_from_Head false",
- " DB /var/lib/fluent-bit/httpdns-logs.db",
- " storage.type filesystem",
- " Mem_Buf_Limit 256MB",
- " Skip_Long_Lines On",
- "",
- )
- }
-
- if hasRole(desired.Roles, fluentBitRoleNode) {
- lines = append(lines,
- "[OUTPUT]",
- " Name http",
- " Match app.http.logs",
- " Host "+desired.ClickHouse.Host,
- " Port "+strconv.Itoa(desired.ClickHouse.Port),
- " URI /?query="+insertHTTP,
- " Format json_lines",
- " http_user ${CH_USER}",
- " http_passwd ${CH_PASSWORD}",
- " json_date_key timestamp",
- " json_date_format epoch",
- " workers 2",
- " net.keepalive On",
- " Retry_Limit False",
- )
- if useTLS {
- lines = append(lines, " tls On")
- if desired.ClickHouse.TLSSkipVerify {
- lines = append(lines, " tls.verify Off")
- } else {
- lines = append(lines, " tls.verify On")
- }
- if strings.TrimSpace(desired.ClickHouse.TLSServerName) != "" {
- lines = append(lines, " tls.vhost "+strings.TrimSpace(desired.ClickHouse.TLSServerName))
- }
- }
- lines = append(lines, "")
- }
-
- if hasRole(desired.Roles, fluentBitRoleDNS) {
- lines = append(lines,
- "[OUTPUT]",
- " Name http",
- " Match app.dns.logs",
- " Host "+desired.ClickHouse.Host,
- " Port "+strconv.Itoa(desired.ClickHouse.Port),
- " URI /?query="+insertDNS,
- " Format json_lines",
- " http_user ${CH_USER}",
- " http_passwd ${CH_PASSWORD}",
- " json_date_key timestamp",
- " json_date_format epoch",
- " workers 2",
- " net.keepalive On",
- " Retry_Limit False",
- )
- if useTLS {
- lines = append(lines, " tls On")
- if desired.ClickHouse.TLSSkipVerify {
- lines = append(lines, " tls.verify Off")
- } else {
- lines = append(lines, " tls.verify On")
- }
- if strings.TrimSpace(desired.ClickHouse.TLSServerName) != "" {
- lines = append(lines, " tls.vhost "+strings.TrimSpace(desired.ClickHouse.TLSServerName))
- }
- }
- lines = append(lines, "")
- }
-
- if hasRole(desired.Roles, fluentBitRoleHTTPDNS) {
- lines = append(lines,
- "[OUTPUT]",
- " Name http",
- " Match app.httpdns.logs",
- " Host "+desired.ClickHouse.Host,
- " Port "+strconv.Itoa(desired.ClickHouse.Port),
- " URI /?query="+insertHTTPDNS,
- " Format json_lines",
- " http_user ${CH_USER}",
- " http_passwd ${CH_PASSWORD}",
- " json_date_key timestamp",
- " json_date_format epoch",
- " workers 2",
- " net.keepalive On",
- " Retry_Limit False",
- )
- if useTLS {
- lines = append(lines, " tls On")
- if desired.ClickHouse.TLSSkipVerify {
- lines = append(lines, " tls.verify Off")
- } else {
- lines = append(lines, " tls.verify On")
- }
- if strings.TrimSpace(desired.ClickHouse.TLSServerName) != "" {
- lines = append(lines, " tls.vhost "+strings.TrimSpace(desired.ClickHouse.TLSServerName))
- }
- }
- lines = append(lines, "")
- }
-
- return strings.Join(lines, "\n"), nil
-}
-
-func renderManagedEnv(ch *systemconfigs.ClickHouseSetting) string {
- user := "default"
- password := ""
- if ch != nil {
- if strings.TrimSpace(ch.User) != "" {
- user = strings.TrimSpace(ch.User)
- }
- password = ch.Password
- }
- return "CH_USER=" + strconv.Quote(user) + "\n" +
- "CH_PASSWORD=" + strconv.Quote(password) + "\n"
-}
-
-func renderManagedMeta(desired *fluentBitDesiredConfig, configContent string, parserContent string, envContent string) (string, *fluentBitManagedMeta, error) {
- hashInput := configContent + "\n---\n" + parserContent + "\n---\n" + envContent + "\n---\n" + strings.Join(desired.Roles, ",")
- hashBytes := sha256.Sum256([]byte(hashInput))
- hash := fmt.Sprintf("%x", hashBytes[:])
-
- meta := &fluentBitManagedMeta{
- Roles: desired.Roles,
- Hash: hash,
- UpdatedAt: time.Now().Unix(),
- SourceVersion: teaconst.Version,
- }
- data, err := json.MarshalIndent(meta, "", " ")
- if err != nil {
- return "", nil, fmt.Errorf("encode fluent-bit managed metadata failed: %w", err)
- }
- return string(data) + "\n", meta, nil
-}
-
-func (this *BaseInstaller) copyLocalFileToRemote(tempDir string, localPath string, remotePath string, mode os.FileMode) error {
- tempFile := tempDir + "/" + filepath.Base(remotePath)
- if err := this.client.Copy(localPath, tempFile, mode); err != nil {
- return fmt.Errorf("upload fluent-bit file '%s' failed: %w", localPath, err)
- }
- _, stderr, err := this.client.Exec("cp -f " + shQuote(tempFile) + " " + shQuote(remotePath) + " && chmod " + fmt.Sprintf("%04o", mode) + " " + shQuote(remotePath))
- if err != nil {
- return fmt.Errorf("install remote fluent-bit file '%s' failed: %w, stderr: %s", remotePath, err, stderr)
- }
- return nil
-}
-
-func (this *BaseInstaller) writeRemoteFileByTemp(tempDir string, remotePath string, content string, mode os.FileMode) error {
- tempFile := tempDir + "/" + filepath.Base(remotePath) + ".tmp"
- if _, err := this.client.WriteFile(tempFile, []byte(content)); err != nil {
- return fmt.Errorf("write temp fluent-bit file '%s' failed: %w", tempFile, err)
- }
-
- _, stderr, err := this.client.Exec("cp -f " + shQuote(tempFile) + " " + shQuote(remotePath) + " && chmod " + fmt.Sprintf("%04o", mode) + " " + shQuote(remotePath))
- if err != nil {
- return fmt.Errorf("write managed fluent-bit file '%s' failed: %w, stderr: %s", remotePath, err, stderr)
- }
- return nil
-}
-
-func (this *BaseInstaller) ensureFluentBitService(tempDir string, binPath string, configChanged bool) error {
- _, _, _ = this.client.Exec("if command -v systemctl >/dev/null 2>&1 && [ ! -f /etc/systemd/system/" + fluentBitServiceName + ".service ] && [ ! -f /lib/systemd/system/" + fluentBitServiceName + ".service ]; then " +
- "cat > /etc/systemd/system/" + fluentBitServiceName + ".service <<'EOF'\n" +
- "[Unit]\n" +
- "Description=Fluent Bit\n" +
- "After=network.target\n" +
- "\n" +
- "[Service]\n" +
- "ExecStart=" + binPath + " -c " + fluentBitMainConfigFile + "\n" +
- "Restart=always\n" +
- "RestartSec=5\n" +
- "\n" +
- "[Install]\n" +
- "WantedBy=multi-user.target\n" +
- "EOF\n" +
- "fi")
-
- stdout, _, err := this.client.Exec("if command -v systemctl >/dev/null 2>&1; then echo 1; else echo 0; fi")
- if err != nil {
- return fmt.Errorf("check systemctl failed: %w", err)
- }
-
- if strings.TrimSpace(stdout) == "1" {
- dropInChanged, err := this.ensureServiceDropIn(tempDir, binPath)
- if err != nil {
- return err
- }
-
- restartRequired := configChanged || dropInChanged
- _, stderr, err := this.client.Exec("systemctl daemon-reload; systemctl enable " + fluentBitServiceName + " >/dev/null 2>&1 || true; " +
- "if systemctl is-active " + fluentBitServiceName + " >/dev/null 2>&1; then " +
- "if [ \"" + boolToString(restartRequired) + "\" = \"1\" ]; then systemctl restart " + fluentBitServiceName + "; fi; " +
- "else systemctl start " + fluentBitServiceName + "; fi")
- if err != nil {
- return fmt.Errorf("ensure fluent-bit service failed: %w, stderr: %s", err, stderr)
- }
- return nil
- }
-
- if configChanged {
- _, _, _ = this.client.Exec("pkill -f \"fluent-bit.*fluent-bit.conf\" >/dev/null 2>&1 || true")
- }
-
- _, _, runningErr := this.client.Exec("pgrep -f \"fluent-bit.*fluent-bit.conf\" >/dev/null 2>&1")
- if runningErr != nil {
- startCmd := "set -a; [ -f " + shQuote(fluentBitManagedEnvFile) + " ] && . " + shQuote(fluentBitManagedEnvFile) + "; set +a; " +
- shQuote(binPath) + " -c " + shQuote(fluentBitMainConfigFile) + " >/dev/null 2>&1 &"
- _, stderr, err := this.client.Exec(startCmd)
- if err != nil {
- return fmt.Errorf("start fluent-bit without systemd failed: %w, stderr: %s", err, stderr)
- }
- }
-
- return nil
-}
-
-func (this *BaseInstaller) ensureServiceDropIn(tempDir string, binPath string) (bool, error) {
- _, stderr, err := this.client.Exec("mkdir -p " + shQuote(fluentBitDropInDir))
- if err != nil {
- return false, fmt.Errorf("prepare fluent-bit drop-in dir failed: %w, stderr: %s", err, stderr)
- }
-
- content := "[Service]\n" +
- "EnvironmentFile=-" + fluentBitManagedEnvFile + "\n" +
- "ExecStart=\n" +
- "ExecStart=" + binPath + " -c " + fluentBitMainConfigFile + "\n"
-
- existing, _, _ := this.client.Exec("if [ -f " + shQuote(fluentBitDropInFile) + " ]; then cat " + shQuote(fluentBitDropInFile) + "; fi")
- if existing == content {
- return false, nil
- }
-
- if err := this.writeRemoteFileByTemp(tempDir, fluentBitDropInFile, content, 0644); err != nil {
- return false, err
- }
- return true, nil
-}
-
-func (this *BaseInstaller) remoteFileExists(path string) (bool, error) {
- stdout, stderr, err := this.client.Exec("if [ -f " + shQuote(path) + " ]; then echo 1; else echo 0; fi")
- if err != nil {
- return false, fmt.Errorf("check remote file '%s' failed: %w, stderr: %s", path, err, stderr)
- }
- return strings.TrimSpace(stdout) == "1", nil
-}
-
-func (this *BaseInstaller) remoteFileContains(path string, pattern string) (bool, error) {
- stdout, stderr, err := this.client.Exec("if grep -F " + shQuote(pattern) + " " + shQuote(path) + " >/dev/null 2>&1; then echo 1; else echo 0; fi")
- if err != nil {
- return false, fmt.Errorf("check remote file content '%s' failed: %w, stderr: %s", path, err, stderr)
- }
- return strings.TrimSpace(stdout) == "1", nil
-}
-
-func shQuote(value string) string {
- if value == "" {
- return "''"
- }
- return "'" + strings.ReplaceAll(value, "'", "'\"'\"'") + "'"
-}
-
-func boolToString(v bool) string {
- if v {
- return "1"
- }
- return "0"
-}
diff --git a/EdgeAPI/internal/installers/installer_base.go b/EdgeAPI/internal/installers/installer_base.go
index ca482b8..79f9f65 100644
--- a/EdgeAPI/internal/installers/installer_base.go
+++ b/EdgeAPI/internal/installers/installer_base.go
@@ -279,3 +279,27 @@ func (this *BaseInstaller) uname() (uname string) {
return "x86_64 GNU/Linux"
}
+
+func parseOSRelease(content string) map[string]string {
+ result := map[string]string{}
+ lines := strings.Split(content, "\n")
+ for _, line := range lines {
+ line = strings.TrimSpace(line)
+ if line == "" || strings.HasPrefix(line, "#") || !strings.Contains(line, "=") {
+ continue
+ }
+ parts := strings.SplitN(line, "=", 2)
+ key := strings.TrimSpace(parts[0])
+ value := strings.TrimSpace(parts[1])
+ value = strings.Trim(value, "\"")
+ result[key] = value
+ }
+ return result
+}
+
+func shQuote(s string) string {
+ if len(s) == 0 {
+ return "''"
+ }
+ return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") + "'"
+}
diff --git a/EdgeAPI/internal/installers/installer_httpdns_node.go b/EdgeAPI/internal/installers/installer_httpdns_node.go
index f93b600..638cab2 100644
--- a/EdgeAPI/internal/installers/installer_httpdns_node.go
+++ b/EdgeAPI/internal/installers/installer_httpdns_node.go
@@ -131,11 +131,6 @@ https.key: "${keyFile}"`)
return fmt.Errorf("write '%s': %w", configFile, err)
}
- err = i.SetupFluentBit(nodeconfigs.NodeRoleHTTPDNS)
- if err != nil {
- installStatus.ErrorCode = "SETUP_FLUENT_BIT_FAILED"
- return fmt.Errorf("setup fluent-bit failed: %w", err)
- }
startCmdPrefix := "cd " + shQuote(appDir+"/configs") + " && ../bin/edge-httpdns "
diff --git a/EdgeAPI/internal/installers/installer_node.go b/EdgeAPI/internal/installers/installer_node.go
index d0e6de3..e65829e 100644
--- a/EdgeAPI/internal/installers/installer_node.go
+++ b/EdgeAPI/internal/installers/installer_node.go
@@ -137,12 +137,6 @@ secret: "${nodeSecret}"`)
}
}
- // 在线安装/更新 Fluent Bit(与边缘节点安装流程联动)
- err = this.SetupFluentBit(nodeconfigs.NodeRoleNode)
- if err != nil {
- installStatus.ErrorCode = "SETUP_FLUENT_BIT_FAILED"
- return fmt.Errorf("setup fluent-bit failed: %w", err)
- }
// 测试
_, stderr, err = this.client.Exec(dir + "/edge-node/bin/edge-node test")
diff --git a/EdgeAPI/internal/installers/installer_ns_node_plus.go b/EdgeAPI/internal/installers/installer_ns_node_plus.go
index cc23d56..39dadbb 100644
--- a/EdgeAPI/internal/installers/installer_ns_node_plus.go
+++ b/EdgeAPI/internal/installers/installer_ns_node_plus.go
@@ -139,12 +139,6 @@ secret: "${nodeSecret}"`)
}
}
- // 在线安装/更新 Fluent Bit(与 DNS 节点安装流程联动)
- err = this.SetupFluentBit(nodeconfigs.NodeRoleDNS)
- if err != nil {
- installStatus.ErrorCode = "SETUP_FLUENT_BIT_FAILED"
- return fmt.Errorf("setup fluent-bit failed: %w", err)
- }
// 测试
_, stderr, err = this.client.Exec(dir + "/edge-dns/bin/edge-dns test")
diff --git a/EdgeAPI/internal/nodes/api_node_services_hook_plus.go b/EdgeAPI/internal/nodes/api_node_services_hook_plus.go
index 2738227..3b5c5f7 100644
--- a/EdgeAPI/internal/nodes/api_node_services_hook_plus.go
+++ b/EdgeAPI/internal/nodes/api_node_services_hook_plus.go
@@ -7,6 +7,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/accounts"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/anti-ddos"
+ httpdnsServices "github.com/TeaOSLab/EdgeAPI/internal/rpc/services/httpdns"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/nameservers"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/posts"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/reporters"
@@ -313,4 +314,9 @@ func APINodeServicesRegister(node *APINode, server *grpc.Server) {
pb.RegisterPostCategoryServiceServer(server, instance)
node.rest(instance)
}
+ {
+ var instance = node.serviceInstance(&httpdnsServices.HTTPDNSBoardService{}).(*httpdnsServices.HTTPDNSBoardService)
+ pb.RegisterHTTPDNSBoardServiceServer(server, instance)
+ node.rest(instance)
+ }
}
diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_board.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_board.go
new file mode 100644
index 0000000..68ca624
--- /dev/null
+++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_board.go
@@ -0,0 +1,324 @@
+package httpdns
+
+import (
+ "context"
+ "time"
+
+ "github.com/TeaOSLab/EdgeAPI/internal/clickhouse"
+ "github.com/TeaOSLab/EdgeAPI/internal/db/models"
+ "github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
+ "github.com/TeaOSLab/EdgeAPI/internal/utils"
+ "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
+ "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
+ "github.com/iwind/TeaGo/dbs"
+ timeutil "github.com/iwind/TeaGo/utils/time"
+)
+
+// HTTPDNSBoardService HTTPDNS 仪表盘服务
+type HTTPDNSBoardService struct {
+ services.BaseService
+}
+
+// ComposeHTTPDNSBoard 组合看板数据
+func (this *HTTPDNSBoardService) ComposeHTTPDNSBoard(ctx context.Context, req *pb.ComposeHTTPDNSBoardRequest) (*pb.ComposeHTTPDNSBoardResponse, error) {
+ _, err := this.ValidateAdmin(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ tx := this.NullTx()
+ result := &pb.ComposeHTTPDNSBoardResponse{}
+
+ countApps, err := models.SharedHTTPDNSAppDAO.CountEnabledApps(tx, "")
+ if err != nil {
+ return nil, err
+ }
+ result.CountApps = countApps
+
+ countDomains, err := models.SharedHTTPDNSDomainDAO.CountEnabledDomains(tx, 0)
+ if err != nil {
+ return nil, err
+ }
+ result.CountDomains = countDomains
+
+ countClusters, err := models.SharedHTTPDNSClusterDAO.CountEnabledClusters(tx, "")
+ if err != nil {
+ return nil, err
+ }
+ result.CountClusters = countClusters
+
+ allNodes, err := models.SharedHTTPDNSNodeDAO.ListEnabledNodes(tx, 0)
+ if err != nil {
+ return nil, err
+ }
+ result.CountNodes = int64(len(allNodes))
+
+ var countOffline int64
+ for _, node := range allNodes {
+ if !node.IsActive {
+ countOffline++
+ }
+ }
+ result.CountOfflineNodes = countOffline
+
+ hourFrom := timeutil.Format("YmdH", time.Now().Add(-23*time.Hour))
+ hourTo := timeutil.Format("YmdH")
+ dayFrom := timeutil.Format("Ymd", time.Now().AddDate(0, 0, -14))
+ dayTo := timeutil.Format("Ymd")
+ todayFrom := timeutil.Format("Ymd", time.Now().Add(-24*time.Hour))
+
+ store := clickhouse.NewHTTPDNSAccessLogsStore()
+ if store.Client().IsConfigured() {
+ err = this.composeTrafficAndRanksFromClickHouse(ctx, tx, store, result, hourFrom, hourTo, dayFrom, dayTo, todayFrom)
+ }
+ if err != nil || !store.Client().IsConfigured() {
+ err = this.composeTrafficAndRanksFromMySQL(tx, result, hourFrom, hourTo, dayFrom, dayTo, todayFrom)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ err = this.fillNodeValues(tx, result)
+ if err != nil {
+ return nil, err
+ }
+
+ return result, nil
+}
+
+func (this *HTTPDNSBoardService) composeTrafficAndRanksFromClickHouse(ctx context.Context, tx *dbs.Tx, store *clickhouse.HTTPDNSAccessLogsStore, result *pb.ComposeHTTPDNSBoardResponse, hourFrom string, hourTo string, dayFrom string, dayTo string, todayFrom string) error {
+ hourlyStats, err := store.FindHourlyStats(ctx, hourFrom, hourTo)
+ if err != nil {
+ return err
+ }
+ hourlyMap := map[string]*clickhouse.HTTPDNSAccessLogHourlyStat{}
+ for _, stat := range hourlyStats {
+ hourlyMap[stat.Hour] = stat
+ }
+ hours, err := utils.RangeHours(hourFrom, hourTo)
+ if err != nil {
+ return err
+ }
+ for _, hour := range hours {
+ stat, ok := hourlyMap[hour]
+ if ok {
+ result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_HourlyTrafficStat{
+ Hour: hour,
+ CountRequests: stat.CountRequests,
+ })
+ } else {
+ result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_HourlyTrafficStat{Hour: hour})
+ }
+ }
+
+ dailyStats, err := store.FindDailyStats(ctx, dayFrom, dayTo)
+ if err != nil {
+ return err
+ }
+ dailyMap := map[string]*clickhouse.HTTPDNSAccessLogDailyStat{}
+ for _, stat := range dailyStats {
+ dailyMap[stat.Day] = stat
+ }
+ days, err := utils.RangeDays(dayFrom, dayTo)
+ if err != nil {
+ return err
+ }
+ for _, day := range days {
+ stat, ok := dailyMap[day]
+ if ok {
+ result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_DailyTrafficStat{
+ Day: day,
+ CountRequests: stat.CountRequests,
+ })
+ } else {
+ result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_DailyTrafficStat{Day: day})
+ }
+ }
+
+ topAppStats, err := store.ListTopApps(ctx, todayFrom, dayTo, 10)
+ if err != nil {
+ return err
+ }
+ for _, stat := range topAppStats {
+ appName := stat.AppName
+ if len(appName) == 0 {
+ appName = stat.AppId
+ }
+ result.TopAppStats = append(result.TopAppStats, &pb.ComposeHTTPDNSBoardResponse_TopAppStat{
+ AppId: 0,
+ AppName: appName,
+ CountRequests: stat.CountRequests,
+ })
+ }
+
+ topDomainStats, err := store.ListTopDomains(ctx, todayFrom, dayTo, 10)
+ if err != nil {
+ return err
+ }
+ for _, stat := range topDomainStats {
+ result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeHTTPDNSBoardResponse_TopDomainStat{
+ DomainName: stat.Domain,
+ CountRequests: stat.CountRequests,
+ })
+ }
+
+ topNodeStats, err := store.ListTopNodes(ctx, todayFrom, dayTo, 10)
+ if err != nil {
+ return err
+ }
+ for _, stat := range topNodeStats {
+ nodeName := ""
+ node, nodeErr := models.SharedHTTPDNSNodeDAO.FindEnabledNode(tx, int64(stat.NodeId))
+ if nodeErr == nil && node != nil {
+ nodeName = node.Name
+ }
+ if len(nodeName) == 0 {
+ continue
+ }
+ result.TopNodeStats = append(result.TopNodeStats, &pb.ComposeHTTPDNSBoardResponse_TopNodeStat{
+ ClusterId: int64(stat.ClusterId),
+ NodeId: int64(stat.NodeId),
+ NodeName: nodeName,
+ CountRequests: stat.CountRequests,
+ })
+ }
+
+ return nil
+}
+
+func (this *HTTPDNSBoardService) composeTrafficAndRanksFromMySQL(tx *dbs.Tx, result *pb.ComposeHTTPDNSBoardResponse, hourFrom string, hourTo string, dayFrom string, dayTo string, todayFrom string) error {
+ hourlyStats, err := models.SharedHTTPDNSAccessLogDAO.FindHourlyStats(tx, hourFrom, hourTo)
+ if err != nil {
+ return err
+ }
+ hourlyMap := map[string]*models.HTTPDNSAccessLogHourlyStat{}
+ for _, stat := range hourlyStats {
+ hourlyMap[stat.Hour] = stat
+ }
+ hours, err := utils.RangeHours(hourFrom, hourTo)
+ if err != nil {
+ return err
+ }
+ for _, hour := range hours {
+ stat, ok := hourlyMap[hour]
+ if ok {
+ result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_HourlyTrafficStat{
+ Hour: hour,
+ CountRequests: stat.CountRequests,
+ })
+ } else {
+ result.HourlyTrafficStats = append(result.HourlyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_HourlyTrafficStat{Hour: hour})
+ }
+ }
+
+ dailyStats, err := models.SharedHTTPDNSAccessLogDAO.FindDailyStats(tx, dayFrom, dayTo)
+ if err != nil {
+ return err
+ }
+ dailyMap := map[string]*models.HTTPDNSAccessLogDailyStat{}
+ for _, stat := range dailyStats {
+ dailyMap[stat.Day] = stat
+ }
+ days, err := utils.RangeDays(dayFrom, dayTo)
+ if err != nil {
+ return err
+ }
+ for _, day := range days {
+ stat, ok := dailyMap[day]
+ if ok {
+ result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_DailyTrafficStat{
+ Day: day,
+ CountRequests: stat.CountRequests,
+ })
+ } else {
+ result.DailyTrafficStats = append(result.DailyTrafficStats, &pb.ComposeHTTPDNSBoardResponse_DailyTrafficStat{Day: day})
+ }
+ }
+
+ topAppStats, err := models.SharedHTTPDNSAccessLogDAO.ListTopApps(tx, todayFrom, dayTo, 10)
+ if err != nil {
+ return err
+ }
+ for _, stat := range topAppStats {
+ appName := stat.AppName
+ if len(appName) == 0 {
+ appName = stat.AppId
+ }
+ result.TopAppStats = append(result.TopAppStats, &pb.ComposeHTTPDNSBoardResponse_TopAppStat{
+ AppId: 0,
+ AppName: appName,
+ CountRequests: stat.CountRequests,
+ })
+ }
+
+ topDomainStats, err := models.SharedHTTPDNSAccessLogDAO.ListTopDomains(tx, todayFrom, dayTo, 10)
+ if err != nil {
+ return err
+ }
+ for _, stat := range topDomainStats {
+ result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeHTTPDNSBoardResponse_TopDomainStat{
+ DomainName: stat.Domain,
+ CountRequests: stat.CountRequests,
+ })
+ }
+
+ topNodeStats, err := models.SharedHTTPDNSAccessLogDAO.ListTopNodes(tx, todayFrom, dayTo, 10)
+ if err != nil {
+ return err
+ }
+ for _, stat := range topNodeStats {
+ nodeName := ""
+ node, nodeErr := models.SharedHTTPDNSNodeDAO.FindEnabledNode(tx, int64(stat.NodeId))
+ if nodeErr == nil && node != nil {
+ nodeName = node.Name
+ }
+ if len(nodeName) == 0 {
+ continue
+ }
+ result.TopNodeStats = append(result.TopNodeStats, &pb.ComposeHTTPDNSBoardResponse_TopNodeStat{
+ ClusterId: int64(stat.ClusterId),
+ NodeId: int64(stat.NodeId),
+ NodeName: nodeName,
+ CountRequests: stat.CountRequests,
+ })
+ }
+
+ return nil
+}
+
+func (this *HTTPDNSBoardService) fillNodeValues(tx *dbs.Tx, result *pb.ComposeHTTPDNSBoardResponse) error {
+ cpuValues, err := models.SharedNodeValueDAO.ListValuesForHTTPDNSNodes(tx, nodeconfigs.NodeValueItemCPU, "usage", nodeconfigs.NodeValueRangeMinute)
+ if err != nil {
+ return err
+ }
+ for _, v := range cpuValues {
+ result.CpuNodeValues = append(result.CpuNodeValues, &pb.NodeValue{
+ ValueJSON: v.Value,
+ CreatedAt: int64(v.CreatedAt),
+ })
+ }
+
+ memoryValues, err := models.SharedNodeValueDAO.ListValuesForHTTPDNSNodes(tx, nodeconfigs.NodeValueItemMemory, "usage", nodeconfigs.NodeValueRangeMinute)
+ if err != nil {
+ return err
+ }
+ for _, v := range memoryValues {
+ result.MemoryNodeValues = append(result.MemoryNodeValues, &pb.NodeValue{
+ ValueJSON: v.Value,
+ CreatedAt: int64(v.CreatedAt),
+ })
+ }
+
+ loadValues, err := models.SharedNodeValueDAO.ListValuesForHTTPDNSNodes(tx, nodeconfigs.NodeValueItemLoad, "load1m", nodeconfigs.NodeValueRangeMinute)
+ if err != nil {
+ return err
+ }
+ for _, v := range loadValues {
+ result.LoadNodeValues = append(result.LoadNodeValues, &pb.NodeValue{
+ ValueJSON: v.Value,
+ CreatedAt: int64(v.CreatedAt),
+ })
+ }
+
+ return nil
+}
diff --git a/EdgeAPI/internal/rpc/services/service_node_value.go b/EdgeAPI/internal/rpc/services/service_node_value.go
index a1ec90d..0484e7a 100644
--- a/EdgeAPI/internal/rpc/services/service_node_value.go
+++ b/EdgeAPI/internal/rpc/services/service_node_value.go
@@ -17,7 +17,7 @@ type NodeValueService struct {
// CreateNodeValue 记录数据
func (this *NodeValueService) CreateNodeValue(ctx context.Context, req *pb.CreateNodeValueRequest) (*pb.RPCSuccess, error) {
- role, nodeId, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS, rpcutils.UserTypeUser)
+ role, nodeId, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS, rpcutils.UserTypeUser, rpcutils.UserTypeHTTPDNS)
if err != nil {
return nil, err
}
@@ -30,6 +30,8 @@ func (this *NodeValueService) CreateNodeValue(ctx context.Context, req *pb.Creat
clusterId, err = models.SharedNodeDAO.FindNodeClusterId(tx, nodeId)
case rpcutils.UserTypeDNS:
clusterId, err = models.SharedNSNodeDAO.FindNodeClusterId(tx, nodeId)
+ case rpcutils.UserTypeHTTPDNS:
+ clusterId, err = models.SharedHTTPDNSNodeDAO.FindNodeClusterId(tx, nodeId)
case rpcutils.UserTypeUser:
}
if err != nil {
diff --git a/EdgeAdmin/build/build.sh b/EdgeAdmin/build/build.sh
index e3eb1ac..d699c4c 100644
--- a/EdgeAdmin/build/build.sh
+++ b/EdgeAdmin/build/build.sh
@@ -97,12 +97,10 @@ function build() {
# create dir & copy files
echo "copying ..."
- if [ ! -d "$DIST" ]; then
- mkdir "$DIST"
- mkdir "$DIST"/bin
- mkdir "$DIST"/configs
- mkdir "$DIST"/logs
- fi
+ rm -rf "$DIST"
+ mkdir -p "$DIST"/bin
+ mkdir -p "$DIST"/configs
+ mkdir -p "$DIST"/logs
cp -R "$ROOT"/../web "$DIST"/
rm -f "$DIST"/web/tmp/*
@@ -135,30 +133,6 @@ function build() {
rm -f "$(basename "$EDGE_API_ZIP_FILE")"
# ensure edge-api package always contains fluent-bit runtime assets/packages
- FLUENT_ROOT="$ROOT/../../deploy/fluent-bit"
- FLUENT_DIST="$DIST/edge-api/deploy/fluent-bit"
- if [ -d "$FLUENT_ROOT" ]; then
- verify_fluent_bit_package_matrix "$FLUENT_ROOT" "$ARCH" || exit 1
- rm -rf "$FLUENT_DIST"
- mkdir -p "$FLUENT_DIST"
-
- FLUENT_FILES=(
- "parsers.conf"
- )
- for file in "${FLUENT_FILES[@]}"; do
- if [ -f "$FLUENT_ROOT/$file" ]; then
- cp "$FLUENT_ROOT/$file" "$FLUENT_DIST/"
- fi
- done
-
- if [ -d "$FLUENT_ROOT/packages" ]; then
- cp -R "$FLUENT_ROOT/packages" "$FLUENT_DIST/"
- fi
-
- rm -f "$FLUENT_DIST/.gitignore"
- rm -f "$FLUENT_DIST"/logs.db*
- rm -rf "$FLUENT_DIST/storage"
- fi
# 鍒犻櫎 MaxMind 鏁版嵁搴撴枃浠讹紙浣跨敤宓屽叆鐨勬暟鎹簱锛屼笉闇€瑕佸閮ㄦ枃浠讹級
find . -name "*.mmdb" -type f -delete
@@ -220,39 +194,6 @@ function build() {
echo "[done]"
}
-function verify_fluent_bit_package_matrix() {
- FLUENT_ROOT=$1
- ARCH=$2
- REQUIRED_FILES=()
- if [ "$ARCH" = "amd64" ]; then
- REQUIRED_FILES=(
- "packages/linux-amd64/fluent-bit_4.2.2_amd64.deb"
- "packages/linux-amd64/fluent-bit-4.2.2-1.x86_64.rpm"
- )
- elif [ "$ARCH" = "arm64" ]; then
- REQUIRED_FILES=(
- "packages/linux-arm64/fluent-bit_4.2.2_arm64.deb"
- "packages/linux-arm64/fluent-bit-4.2.2-1.aarch64.rpm"
- )
- else
- echo "[error] unsupported arch for fluent-bit package validation: $ARCH"
- return 1
- fi
-
- MISSING=0
- for FILE in "${REQUIRED_FILES[@]}"; do
- if [ ! -f "$FLUENT_ROOT/$FILE" ]; then
- echo "[error] fluent-bit matrix package missing: $FLUENT_ROOT/$FILE"
- MISSING=1
- fi
- done
-
- if [ "$MISSING" -ne 0 ]; then
- return 1
- fi
- return 0
-}
-
function lookup-version() {
FILE=$1
VERSION_DATA=$(cat "$FILE")
diff --git a/EdgeAdmin/internal/const/const.go b/EdgeAdmin/internal/const/const.go
index 55a74ae..6eabbb7 100644
--- a/EdgeAdmin/internal/const/const.go
+++ b/EdgeAdmin/internal/const/const.go
@@ -1,9 +1,9 @@
package teaconst
const (
- Version = "1.4.9" //1.3.9
+ Version = "1.5.0" //1.3.9
- APINodeVersion = "1.4.9" //1.3.9
+ APINodeVersion = "1.5.0" //1.3.9
ProductName = "Edge Admin"
ProcessName = "edge-admin"
diff --git a/EdgeAdmin/internal/rpc/rpc_client_plus.go b/EdgeAdmin/internal/rpc/rpc_client_plus.go
index e391146..6eab88e 100644
--- a/EdgeAdmin/internal/rpc/rpc_client_plus.go
+++ b/EdgeAdmin/internal/rpc/rpc_client_plus.go
@@ -248,3 +248,7 @@ func (this *RPCClient) PostCategoryRPC() pb.PostCategoryServiceClient {
func (this *RPCClient) PostRPC() pb.PostServiceClient {
return pb.NewPostServiceClient(this.pickConn())
}
+
+func (this *RPCClient) HTTPDNSBoardRPC() pb.HTTPDNSBoardServiceClient {
+ return pb.NewHTTPDNSBoardServiceClient(this.pickConn())
+}
diff --git a/EdgeAdmin/internal/web/actions/default/clusters/cluster/init_plus.go b/EdgeAdmin/internal/web/actions/default/clusters/cluster/init_plus.go
index c4b8851..3305849 100644
--- a/EdgeAdmin/internal/web/actions/default/clusters/cluster/init_plus.go
+++ b/EdgeAdmin/internal/web/actions/default/clusters/cluster/init_plus.go
@@ -11,7 +11,6 @@ import (
nodethresholds "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/thresholds"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/cc"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/http3"
- networksecurity "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/network-security"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/pages"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/thresholds"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/uam"
@@ -53,7 +52,6 @@ func init() {
GetPost("/thresholds", new(thresholds.IndexAction)).
//
- GetPost("/network-security", new(networksecurity.IndexAction)).
// 节点设置相关
Prefix("/clusters/cluster/node/settings").
diff --git a/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/network-security/index.go b/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/network-security/index.go
deleted file mode 100644
index f620d43..0000000
--- a/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/network-security/index.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus
-
-package networksecurity
-
-import (
- "encoding/json"
- "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
- "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
- "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
- "github.com/iwind/TeaGo/actions"
-)
-
-type IndexAction struct {
- actionutils.ParentAction
-}
-
-func (this *IndexAction) Init() {
- this.Nav("", "setting", "index")
- this.SecondMenu("networkSecurity")
-}
-
-func (this *IndexAction) RunGet(params struct {
- ClusterId int64
-}) {
- policyResp, err := this.RPC().NodeClusterRPC().FindNodeClusterNetworkSecurityPolicy(this.AdminContext(), &pb.FindNodeClusterNetworkSecurityPolicyRequest{
- NodeClusterId: params.ClusterId,
- })
- if err != nil {
- this.ErrorPage(err)
- return
- }
-
- var policy = nodeconfigs.NewNetworkSecurityPolicy()
- if len(policyResp.NetworkSecurityPolicyJSON) > 0 {
- err = json.Unmarshal(policyResp.NetworkSecurityPolicyJSON, policy)
- if err != nil {
- this.ErrorPage(err)
- return
- }
- }
- this.Data["policy"] = policy
-
- this.Show()
-}
-
-func (this *IndexAction) RunPost(params struct {
- ClusterId int64
- Status string
-
- Must *actions.Must
- CSRF *actionutils.CSRF
-}) {
- policyResp, err := this.RPC().NodeClusterRPC().FindNodeClusterNetworkSecurityPolicy(this.AdminContext(), &pb.FindNodeClusterNetworkSecurityPolicyRequest{
- NodeClusterId: params.ClusterId,
- })
- if err != nil {
- this.ErrorPage(err)
- return
- }
-
- var policy = nodeconfigs.NewNetworkSecurityPolicy()
- if len(policyResp.NetworkSecurityPolicyJSON) > 0 {
- err = json.Unmarshal(policyResp.NetworkSecurityPolicyJSON, policy)
- if err != nil {
- this.ErrorPage(err)
- return
- }
- }
-
- policy.Status = params.Status
-
- err = policy.Init()
- if err != nil {
- this.Fail("配置校验失败:" + err.Error())
- return
- }
-
- policyJSON, err := json.Marshal(policy)
- if err != nil {
- this.ErrorPage(err)
- return
- }
-
- _, err = this.RPC().NodeClusterRPC().UpdateNodeClusterNetworkSecurityPolicy(this.AdminContext(), &pb.UpdateNodeClusterNetworkSecurityPolicyRequest{
- NodeClusterId: params.ClusterId,
- NetworkSecurityPolicyJSON: policyJSON,
- })
- if err != nil {
- this.ErrorPage(err)
- return
- }
-
- this.Success()
-}
diff --git a/EdgeAdmin/internal/web/actions/default/clusters/clusterutils/cluster_helper_ext_plus.go b/EdgeAdmin/internal/web/actions/default/clusters/clusterutils/cluster_helper_ext_plus.go
index 9f3b68b..d8c0102 100644
--- a/EdgeAdmin/internal/web/actions/default/clusters/clusterutils/cluster_helper_ext_plus.go
+++ b/EdgeAdmin/internal/web/actions/default/clusters/clusterutils/cluster_helper_ext_plus.go
@@ -44,17 +44,10 @@ func (this *ClusterHelper) filterMenuItems1(items []maps.Map, info *pb.FindEnabl
func (this *ClusterHelper) filterMenuItems2(items []maps.Map, info *pb.FindEnabledNodeClusterConfigInfoResponse, clusterIdString string, selectedItem string, actionPtr actions.ActionWrapper) []maps.Map {
if teaconst.IsPlus {
- items = append(items, maps.Map{
- "name": this.Lang(actionPtr, codes.NodeClusterMenu_SettingSecurityPolicy),
- "url": "/clusters/cluster/settings/network-security?clusterId=" + clusterIdString,
- "isActive": selectedItem == "networkSecurity",
- "isOn": info != nil && info.HasNetworkSecurityPolicy, // TODO 将来 加入 info.HasDDoSProtection
- })
-
- items = append(items, maps.Map{
- "name": "-",
- })
if plusutils.CheckComponent(plusutils.ComponentCodeScheduling) {
+ items = append(items, maps.Map{
+ "name": "-",
+ })
items = append(items, maps.Map{
"name": this.Lang(actionPtr, codes.NodeClusterMenu_SettingSchedule),
"url": "/clusters/cluster/settings/schedule?clusterId=" + clusterIdString,
@@ -89,14 +82,12 @@ func (this *ClusterHelper) filterMenuItems2(items []maps.Map, info *pb.FindEnabl
"isOn": info != nil && info.HasSystemServices,
})
- {
- items = append(items, maps.Map{
- "name": this.Lang(actionPtr, codes.NodeClusterMenu_SettingTOA),
- "url": "/clusters/cluster/settings/toa?clusterId=" + clusterIdString,
- "isActive": selectedItem == "toa",
- "isOn": info != nil && info.IsTOAEnabled,
- })
- }
+ items = append(items, maps.Map{
+ "name": this.Lang(actionPtr, codes.NodeClusterMenu_SettingTOA),
+ "url": "/clusters/cluster/settings/toa?clusterId=" + clusterIdString,
+ "isActive": selectedItem == "toa",
+ "isOn": info != nil && info.IsTOAEnabled,
+ })
}
return items
}
diff --git a/EdgeAdmin/internal/web/actions/default/dashboard/boards/httpdns.go b/EdgeAdmin/internal/web/actions/default/dashboard/boards/httpdns.go
new file mode 100644
index 0000000..3f6bbbf
--- /dev/null
+++ b/EdgeAdmin/internal/web/actions/default/dashboard/boards/httpdns.go
@@ -0,0 +1,127 @@
+// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
+//go:build plus
+
+package boards
+
+import (
+ teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
+ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
+ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dashboard/boards/boardutils"
+ "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
+ "github.com/iwind/TeaGo/maps"
+)
+
+type HTTPDNSAction struct {
+ actionutils.ParentAction
+}
+
+func (this *HTTPDNSAction) Init() {
+ this.Nav("", "", "httpdns")
+ this.ViewDir("@default")
+ this.View("dashboard/boards/httpdns")
+}
+
+func (this *HTTPDNSAction) RunGet(params struct{}) {
+ if !teaconst.IsPlus {
+ this.RedirectURL("/dashboard")
+ return
+ }
+
+ err := boardutils.InitBoard(this.Parent())
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+
+ this.Data["board"] = maps.Map{
+ "countApps": 0,
+ "countDomains": 0,
+ "countClusters": 0,
+ "countNodes": 0,
+ "countOfflineNodes": 0,
+ }
+
+ this.Show()
+}
+
+func (this *HTTPDNSAction) RunPost(params struct{}) {
+ resp, err := this.RPC().HTTPDNSBoardRPC().ComposeHTTPDNSBoard(this.AdminContext(), &pb.ComposeHTTPDNSBoardRequest{})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ this.Data["board"] = maps.Map{
+ "countApps": resp.CountApps,
+ "countDomains": resp.CountDomains,
+ "countClusters": resp.CountClusters,
+ "countNodes": resp.CountNodes,
+ "countOfflineNodes": resp.CountOfflineNodes,
+ }
+
+ {
+ var statMaps = []maps.Map{}
+ for _, stat := range resp.HourlyTrafficStats {
+ statMaps = append(statMaps, maps.Map{
+ "day": stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
+ "hour": stat.Hour[8:],
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["hourlyStats"] = statMaps
+ }
+
+ {
+ var statMaps = []maps.Map{}
+ for _, stat := range resp.DailyTrafficStats {
+ statMaps = append(statMaps, maps.Map{
+ "day": stat.Day[4:6] + "月" + stat.Day[6:] + "日",
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["dailyStats"] = statMaps
+ }
+
+ {
+ var statMaps = []maps.Map{}
+ for _, stat := range resp.TopAppStats {
+ statMaps = append(statMaps, maps.Map{
+ "appId": stat.AppId,
+ "appName": stat.AppName,
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["topAppStats"] = statMaps
+ }
+
+ {
+ var statMaps = []maps.Map{}
+ for _, stat := range resp.TopDomainStats {
+ statMaps = append(statMaps, maps.Map{
+ "domainId": stat.DomainId,
+ "domainName": stat.DomainName,
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["topDomainStats"] = statMaps
+ }
+
+ {
+ var statMaps = []maps.Map{}
+ for _, stat := range resp.TopNodeStats {
+ statMaps = append(statMaps, maps.Map{
+ "clusterId": stat.ClusterId,
+ "nodeId": stat.NodeId,
+ "nodeName": stat.NodeName,
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["topNodeStats"] = statMaps
+ }
+
+ this.Success()
+}
diff --git a/EdgeAdmin/internal/web/actions/default/dashboard/boards/index.go b/EdgeAdmin/internal/web/actions/default/dashboard/boards/index.go
index 2cf3087..e3e43f4 100644
--- a/EdgeAdmin/internal/web/actions/default/dashboard/boards/index.go
+++ b/EdgeAdmin/internal/web/actions/default/dashboard/boards/index.go
@@ -19,6 +19,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
+ stringutil "github.com/iwind/TeaGo/utils/string"
timeutil "github.com/iwind/TeaGo/utils/time"
"regexp"
"time"
@@ -409,5 +410,55 @@ func (this *IndexAction) RunPost(params struct {
}
this.Data["countWeakAdmins"] = countWeakAdminsResp.Count
+ upgradeConfig, err := configloaders.LoadUpgradeConfig()
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ this.Data["autoUpgrade"] = upgradeConfig.AutoUpgrade
+
+ httpdnsNodeUpgradeInfo, err := this.composeHTTPDNSNodeUpgradeInfo()
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ this.Data["httpdnsNodeUpgradeInfo"] = httpdnsNodeUpgradeInfo
+
this.Success()
}
+
+func (this *IndexAction) composeHTTPDNSNodeUpgradeInfo() (maps.Map, error) {
+ clustersResp, err := this.RPC().HTTPDNSClusterRPC().ListHTTPDNSClusters(this.AdminContext(), &pb.ListHTTPDNSClustersRequest{
+ Offset: 0,
+ Size: 10000,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ count := 0
+ version := ""
+ for _, cluster := range clustersResp.Clusters {
+ resp, err := this.RPC().HTTPDNSNodeRPC().FindAllUpgradeHTTPDNSNodesWithClusterId(this.AdminContext(), &pb.FindAllUpgradeHTTPDNSNodesWithClusterIdRequest{
+ ClusterId: cluster.Id,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ count += len(resp.Nodes)
+ for _, nodeUpgrade := range resp.Nodes {
+ if len(nodeUpgrade.NewVersion) == 0 {
+ continue
+ }
+ if len(version) == 0 || stringutil.VersionCompare(version, nodeUpgrade.NewVersion) < 0 {
+ version = nodeUpgrade.NewVersion
+ }
+ }
+ }
+
+ return maps.Map{
+ "count": count,
+ "version": version,
+ }, nil
+}
diff --git a/EdgeAdmin/internal/web/actions/default/dashboard/index.go b/EdgeAdmin/internal/web/actions/default/dashboard/index.go
index 7ac18e6..0737798 100644
--- a/EdgeAdmin/internal/web/actions/default/dashboard/index.go
+++ b/EdgeAdmin/internal/web/actions/default/dashboard/index.go
@@ -245,5 +245,12 @@ func (this *IndexAction) RunPost(params struct{}) {
}
this.Data["countWeakAdmins"] = countWeakAdminsResp.Count
+ upgradeConfig, err := configloaders.LoadUpgradeConfig()
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+ this.Data["autoUpgrade"] = upgradeConfig.AutoUpgrade
+
this.Success()
}
diff --git a/EdgeAdmin/internal/web/actions/default/dashboard/init_plus.go b/EdgeAdmin/internal/web/actions/default/dashboard/init_plus.go
index 67aff3f..f95cd10 100644
--- a/EdgeAdmin/internal/web/actions/default/dashboard/init_plus.go
+++ b/EdgeAdmin/internal/web/actions/default/dashboard/init_plus.go
@@ -22,6 +22,7 @@ func init() {
Get("/waf", new(boards.WafAction)).
Post("/wafLogs", new(boards.WafLogsAction)).
GetPost("/dns", new(boards.DnsAction)).
+ GetPost("/httpdns", new(boards.HTTPDNSAction)).
Get("/user", new(boards.UserAction)).
Get("/events", new(boards.EventsAction)).
Post("/readLogs", new(boards.ReadLogsAction)).
diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/index.go
index df37453..404d601 100644
--- a/EdgeAdmin/internal/web/actions/default/httpdns/index.go
+++ b/EdgeAdmin/internal/web/actions/default/httpdns/index.go
@@ -1,11 +1,110 @@
package httpdns
-import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
+import (
+ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
+ "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
+ "github.com/iwind/TeaGo/maps"
+)
type IndexAction struct {
actionutils.ParentAction
}
-func (this *IndexAction) RunGet(params struct{}) {
- this.RedirectURL("/httpdns/clusters")
+func (this *IndexAction) Init() {
+ this.Nav("", "", "httpdns")
+}
+
+func (this *IndexAction) RunGet(params struct{}) {
+ this.Data["board"] = maps.Map{
+ "countApps": 0,
+ "countDomains": 0,
+ "countClusters": 0,
+ "countNodes": 0,
+ "countOfflineNodes": 0,
+ }
+
+ this.Show()
+}
+
+func (this *IndexAction) RunPost(params struct{}) {
+ resp, err := this.RPC().HTTPDNSBoardRPC().ComposeHTTPDNSBoard(this.AdminContext(), &pb.ComposeHTTPDNSBoardRequest{})
+ if err != nil {
+ this.ErrorPage(err)
+ return
+ }
+
+ this.Data["board"] = maps.Map{
+ "countApps": resp.CountApps,
+ "countDomains": resp.CountDomains,
+ "countClusters": resp.CountClusters,
+ "countNodes": resp.CountNodes,
+ "countOfflineNodes": resp.CountOfflineNodes,
+ }
+
+ {
+ statMaps := []maps.Map{}
+ for _, stat := range resp.HourlyTrafficStats {
+ statMaps = append(statMaps, maps.Map{
+ "day": stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
+ "hour": stat.Hour[8:],
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["hourlyStats"] = statMaps
+ }
+
+ {
+ statMaps := []maps.Map{}
+ for _, stat := range resp.DailyTrafficStats {
+ statMaps = append(statMaps, maps.Map{
+ "day": stat.Day[4:6] + "月" + stat.Day[6:] + "日",
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["dailyStats"] = statMaps
+ }
+
+ {
+ statMaps := []maps.Map{}
+ for _, stat := range resp.TopAppStats {
+ statMaps = append(statMaps, maps.Map{
+ "appId": stat.AppId,
+ "appName": stat.AppName,
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["topAppStats"] = statMaps
+ }
+
+ {
+ statMaps := []maps.Map{}
+ for _, stat := range resp.TopDomainStats {
+ statMaps = append(statMaps, maps.Map{
+ "domainId": stat.DomainId,
+ "domainName": stat.DomainName,
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["topDomainStats"] = statMaps
+ }
+
+ {
+ statMaps := []maps.Map{}
+ for _, stat := range resp.TopNodeStats {
+ statMaps = append(statMaps, maps.Map{
+ "clusterId": stat.ClusterId,
+ "nodeId": stat.NodeId,
+ "nodeName": stat.NodeName,
+ "countRequests": stat.CountRequests,
+ "bytes": stat.Bytes,
+ })
+ }
+ this.Data["topNodeStats"] = statMaps
+ }
+
+ this.Success()
}
diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/init.go b/EdgeAdmin/internal/web/actions/default/httpdns/init.go
index 78dc22b..ddede79 100644
--- a/EdgeAdmin/internal/web/actions/default/httpdns/init.go
+++ b/EdgeAdmin/internal/web/actions/default/httpdns/init.go
@@ -11,9 +11,9 @@ func init() {
server.
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeHttpDNS)).
Data("teaMenu", "httpdns").
- Data("teaSubMenu", "cluster").
+ Data("teaSubMenu", "board").
Prefix("/httpdns").
- Get("", new(IndexAction)).
+ GetPost("", new(IndexAction)).
GetPost("/addPortPopup", new(AddPortPopupAction)).
EndAll()
})
diff --git a/EdgeAdmin/internal/web/actions/default/servers/server/settings/access/createPopup_plus.go b/EdgeAdmin/internal/web/actions/default/servers/server/settings/access/createPopup_plus.go
index cec6a2a..a33acdc 100644
--- a/EdgeAdmin/internal/web/actions/default/servers/server/settings/access/createPopup_plus.go
+++ b/EdgeAdmin/internal/web/actions/default/servers/server/settings/access/createPopup_plus.go
@@ -25,7 +25,7 @@ func (this *CreatePopupAction) Init() {
}
func (this *CreatePopupAction) RunGet(params struct{}) {
- var authMethods = []*serverconfigs.HTTPAuthTypeDefinition{}
+ authMethods := []*serverconfigs.HTTPAuthTypeDefinition{}
for _, method := range serverconfigs.FindAllHTTPAuthTypes(teaconst.Role) {
if !method.IsPlus || (method.IsPlus && teaconst.IsPlus) {
authMethods = append(authMethods, method)
@@ -59,6 +59,10 @@ func (this *CreatePopupAction) RunPost(params struct {
TypeDTimestampParamName string
TypeDLife int
+ // TypeE
+ TypeESecret string
+ TypeELife int
+
// BasicAuth
HttpAuthBasicAuthUsersJSON []byte
BasicAuthRealm string
@@ -81,29 +85,25 @@ func (this *CreatePopupAction) RunPost(params struct {
Field("type", params.Type).
Require("请输入鉴权类型")
- var ref = &serverconfigs.HTTPAuthPolicyRef{IsOn: true}
+ ref := &serverconfigs.HTTPAuthPolicyRef{IsOn: true}
var method serverconfigs.HTTPAuthMethodInterface
- // 扩展名
- var exts = utils.NewStringsStream(params.Exts).
+ exts := utils.NewStringsStream(params.Exts).
Map(strings.TrimSpace, strings.ToLower).
Filter(utils.FilterNotEmpty).
Map(utils.MapAddPrefixFunc(".")).
Unique().
Result()
- // 域名
- var domains = []string{}
+ domains := []string{}
if len(params.DomainsJSON) > 0 {
- var rawDomains = []string{}
+ rawDomains := []string{}
err := json.Unmarshal(params.DomainsJSON, &rawDomains)
if err != nil {
this.ErrorPage(err)
return
}
- // TODO 如果用户填写了一个网址,应该分析域名并填入
-
domains = utils.NewStringsStream(rawDomains).
Map(strings.TrimSpace, strings.ToLower).
Filter(utils.FilterNotEmpty).
@@ -116,11 +116,11 @@ func (this *CreatePopupAction) RunPost(params struct {
params.Must.
Field("typeASecret", params.TypeASecret).
Require("请输入鉴权密钥").
- MaxLength(40, "鉴权密钥不能超过40个字符").
- Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母、数字").
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字").
Field("typeASignParamName", params.TypeASignParamName).
Require("请输入签名参数").
- Match(`^[a-zA-Z0-9_]{1,40}$`, "签名参数中只能包含字母、数字、下划线")
+ Match(`^[a-zA-Z0-9_]{1,40}$`, "签名参数中只能包含字母、数字和下划线")
if params.TypeALife < 0 {
params.TypeALife = 0
@@ -135,8 +135,8 @@ func (this *CreatePopupAction) RunPost(params struct {
params.Must.
Field("typeBSecret", params.TypeBSecret).
Require("请输入鉴权密钥").
- MaxLength(40, "鉴权密钥不能超过40个字符").
- Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母、数字")
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字")
method = &serverconfigs.HTTPAuthTypeBMethod{
Secret: params.TypeBSecret,
@@ -146,8 +146,8 @@ func (this *CreatePopupAction) RunPost(params struct {
params.Must.
Field("typeCSecret", params.TypeCSecret).
Require("请输入鉴权密钥").
- MaxLength(40, "鉴权密钥不能超过40个字符").
- Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母、数字")
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字")
method = &serverconfigs.HTTPAuthTypeCMethod{
Secret: params.TypeCSecret,
@@ -157,14 +157,14 @@ func (this *CreatePopupAction) RunPost(params struct {
params.Must.
Field("typeDSecret", params.TypeDSecret).
Require("请输入鉴权密钥").
- MaxLength(40, "鉴权密钥不能超过40个字符").
- Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母、数字").
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字").
Field("typeDSignParamName", params.TypeDSignParamName).
Require("请输入签名参数").
- Match(`^[a-zA-Z0-9_]{1,40}$`, "签名参数中只能包含字母、数字、下划线").
+ Match(`^[a-zA-Z0-9_]{1,40}$`, "签名参数中只能包含字母、数字和下划线").
Field("typeDTimestampParamName", params.TypeDTimestampParamName).
- Require("请输入时间戳参数").
- Match(`^[a-zA-Z0-9_]{1,40}$`, "时间戳参数中只能包含字母、数字、下划线")
+ Require("请输入时间参数").
+ Match(`^[a-zA-Z0-9_]{1,40}$`, "时间参数中只能包含字母、数字和下划线")
method = &serverconfigs.HTTPAuthTypeDMethod{
Secret: params.TypeDSecret,
@@ -172,15 +172,26 @@ func (this *CreatePopupAction) RunPost(params struct {
TimestampParamName: params.TypeDTimestampParamName,
Life: params.TypeDLife,
}
+ case serverconfigs.HTTPAuthTypeTypeE:
+ params.Must.
+ Field("typeESecret", params.TypeESecret).
+ Require("请输入鉴权密钥").
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字")
+
+ method = &serverconfigs.HTTPAuthTypeEMethod{
+ Secret: params.TypeESecret,
+ Life: params.TypeELife,
+ }
case serverconfigs.HTTPAuthTypeBasicAuth:
- var users = []*serverconfigs.HTTPAuthBasicMethodUser{}
+ users := []*serverconfigs.HTTPAuthBasicMethodUser{}
err := json.Unmarshal(params.HttpAuthBasicAuthUsersJSON, &users)
if err != nil {
this.ErrorPage(err)
return
}
if len(users) == 0 {
- this.Fail("请添加至少一个用户")
+ this.Fail("请至少添加一个用户")
}
method = &serverconfigs.HTTPAuthBasicMethod{
Users: users,
@@ -188,8 +199,9 @@ func (this *CreatePopupAction) RunPost(params struct {
Charset: params.BasicAuthCharset,
}
case serverconfigs.HTTPAuthTypeSubRequest:
- params.Must.Field("subRequestURL", params.SubRequestURL).
- Require("请输入子请求URL")
+ params.Must.
+ Field("subRequestURL", params.SubRequestURL).
+ Require("请输入子请求 URL")
if params.SubRequestFollowRequest {
params.SubRequestMethod = ""
}
@@ -198,7 +210,7 @@ func (this *CreatePopupAction) RunPost(params struct {
Method: params.SubRequestMethod,
}
default:
- this.Fail("不支持的鉴权类型'" + params.Type + "'")
+ this.Fail("不支持的鉴权类型 '" + params.Type + "'")
}
if method == nil {
@@ -214,7 +226,7 @@ func (this *CreatePopupAction) RunPost(params struct {
return
}
- var paramsMap = maps.Map{}
+ paramsMap := maps.Map{}
err = json.Unmarshal(methodJSON, ¶msMap)
if err != nil {
this.ErrorPage(err)
@@ -231,6 +243,7 @@ func (this *CreatePopupAction) RunPost(params struct {
return
}
defer this.CreateLogInfo(codes.HTTPAuthPolicy_LogCreateHTTPAuthPolicy, createResp.HttpAuthPolicyId)
+
ref.AuthPolicyId = createResp.HttpAuthPolicyId
ref.AuthPolicy = &serverconfigs.HTTPAuthPolicy{
Id: createResp.HttpAuthPolicyId,
diff --git a/EdgeAdmin/internal/web/actions/default/servers/server/settings/access/updatePopup_plus.go b/EdgeAdmin/internal/web/actions/default/servers/server/settings/access/updatePopup_plus.go
index 4259e76..812519d 100644
--- a/EdgeAdmin/internal/web/actions/default/servers/server/settings/access/updatePopup_plus.go
+++ b/EdgeAdmin/internal/web/actions/default/servers/server/settings/access/updatePopup_plus.go
@@ -27,7 +27,7 @@ func (this *UpdatePopupAction) Init() {
func (this *UpdatePopupAction) RunGet(params struct {
PolicyId int64
}) {
- var authMethods = []*serverconfigs.HTTPAuthTypeDefinition{}
+ authMethods := []*serverconfigs.HTTPAuthTypeDefinition{}
for _, method := range serverconfigs.FindAllHTTPAuthTypes(teaconst.Role) {
if !method.IsPlus || (method.IsPlus && teaconst.IsPlus) {
authMethods = append(authMethods, method)
@@ -47,7 +47,7 @@ func (this *UpdatePopupAction) RunGet(params struct {
return
}
- var authParams = map[string]interface{}{}
+ authParams := map[string]interface{}{}
if len(policy.ParamsJSON) > 0 {
err = json.Unmarshal(policy.ParamsJSON, &authParams)
if err != nil {
@@ -91,6 +91,10 @@ func (this *UpdatePopupAction) RunPost(params struct {
TypeDTimestampParamName string
TypeDLife int
+ // TypeE
+ TypeESecret string
+ TypeELife int
+
// BasicAuth
HttpAuthBasicAuthUsersJSON []byte
BasicAuthRealm string
@@ -125,29 +129,25 @@ func (this *UpdatePopupAction) RunPost(params struct {
Field("name", params.Name).
Require("请输入名称")
- var ref = &serverconfigs.HTTPAuthPolicyRef{IsOn: true}
+ ref := &serverconfigs.HTTPAuthPolicyRef{IsOn: true}
var method serverconfigs.HTTPAuthMethodInterface
- // 扩展名
- var exts = utils.NewStringsStream(params.Exts).
+ exts := utils.NewStringsStream(params.Exts).
Map(strings.TrimSpace, strings.ToLower).
Filter(utils.FilterNotEmpty).
Map(utils.MapAddPrefixFunc(".")).
Unique().
Result()
- // 域名
- var domains = []string{}
+ domains := []string{}
if len(params.DomainsJSON) > 0 {
- var rawDomains = []string{}
+ rawDomains := []string{}
err := json.Unmarshal(params.DomainsJSON, &rawDomains)
if err != nil {
this.ErrorPage(err)
return
}
- // TODO 如果用户填写了一个网址,应该分析域名并填入
-
domains = utils.NewStringsStream(rawDomains).
Map(strings.TrimSpace, strings.ToLower).
Filter(utils.FilterNotEmpty).
@@ -160,11 +160,11 @@ func (this *UpdatePopupAction) RunPost(params struct {
params.Must.
Field("typeASecret", params.TypeASecret).
Require("请输入鉴权密钥").
- MaxLength(40, "鉴权密钥不能超过40个字符").
- Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母、数字").
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字").
Field("typeASignParamName", params.TypeASignParamName).
Require("请输入签名参数").
- Match(`^[a-zA-Z0-9_]{1,40}$`, "签名参数中只能包含字母、数字、下划线")
+ Match(`^[a-zA-Z0-9_]{1,40}$`, "签名参数中只能包含字母、数字和下划线")
if params.TypeALife < 0 {
params.TypeALife = 0
@@ -179,8 +179,8 @@ func (this *UpdatePopupAction) RunPost(params struct {
params.Must.
Field("typeBSecret", params.TypeBSecret).
Require("请输入鉴权密钥").
- MaxLength(40, "鉴权密钥不能超过40个字符").
- Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母、数字")
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字")
method = &serverconfigs.HTTPAuthTypeBMethod{
Secret: params.TypeBSecret,
@@ -190,8 +190,8 @@ func (this *UpdatePopupAction) RunPost(params struct {
params.Must.
Field("typeCSecret", params.TypeCSecret).
Require("请输入鉴权密钥").
- MaxLength(40, "鉴权密钥不能超过40个字符").
- Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母、数字")
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字")
method = &serverconfigs.HTTPAuthTypeCMethod{
Secret: params.TypeCSecret,
@@ -201,14 +201,14 @@ func (this *UpdatePopupAction) RunPost(params struct {
params.Must.
Field("typeDSecret", params.TypeDSecret).
Require("请输入鉴权密钥").
- MaxLength(40, "鉴权密钥不能超过40个字符").
- Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母、数字").
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字").
Field("typeDSignParamName", params.TypeDSignParamName).
Require("请输入签名参数").
- Match(`^[a-zA-Z0-9_]{1,40}$`, "签名参数中只能包含字母、数字、下划线").
+ Match(`^[a-zA-Z0-9_]{1,40}$`, "签名参数中只能包含字母、数字和下划线").
Field("typeDTimestampParamName", params.TypeDTimestampParamName).
- Require("请输入时间戳参数").
- Match(`^[a-zA-Z0-9_]{1,40}$`, "时间戳参数中只能包含字母、数字、下划线")
+ Require("请输入时间参数").
+ Match(`^[a-zA-Z0-9_]{1,40}$`, "时间参数中只能包含字母、数字和下划线")
method = &serverconfigs.HTTPAuthTypeDMethod{
Secret: params.TypeDSecret,
@@ -216,6 +216,17 @@ func (this *UpdatePopupAction) RunPost(params struct {
TimestampParamName: params.TypeDTimestampParamName,
Life: params.TypeDLife,
}
+ case serverconfigs.HTTPAuthTypeTypeE:
+ params.Must.
+ Field("typeESecret", params.TypeESecret).
+ Require("请输入鉴权密钥").
+ MaxLength(40, "鉴权密钥长度不能超过40个字符").
+ Match(`^[a-zA-Z0-9]{1,40}$`, "鉴权密钥中只能包含字母和数字")
+
+ method = &serverconfigs.HTTPAuthTypeEMethod{
+ Secret: params.TypeESecret,
+ Life: params.TypeELife,
+ }
case serverconfigs.HTTPAuthTypeBasicAuth:
users := []*serverconfigs.HTTPAuthBasicMethodUser{}
err := json.Unmarshal(params.HttpAuthBasicAuthUsersJSON, &users)
@@ -224,7 +235,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
return
}
if len(users) == 0 {
- this.Fail("请添加至少一个用户")
+ this.Fail("请至少添加一个用户")
}
method = &serverconfigs.HTTPAuthBasicMethod{
Users: users,
@@ -232,8 +243,9 @@ func (this *UpdatePopupAction) RunPost(params struct {
Charset: params.BasicAuthCharset,
}
case serverconfigs.HTTPAuthTypeSubRequest:
- params.Must.Field("subRequestURL", params.SubRequestURL).
- Require("请输入子请求URL")
+ params.Must.
+ Field("subRequestURL", params.SubRequestURL).
+ Require("请输入子请求 URL")
if params.SubRequestFollowRequest {
params.SubRequestMethod = ""
}
@@ -242,7 +254,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
Method: params.SubRequestMethod,
}
default:
- this.Fail("不支持的鉴权类型'" + policyType + "'")
+ this.Fail("不支持的鉴权类型 '" + policyType + "'")
}
if method == nil {
@@ -275,6 +287,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
this.ErrorPage(err)
return
}
+
ref.AuthPolicy = &serverconfigs.HTTPAuthPolicy{
Id: params.PolicyId,
Name: params.Name,
diff --git a/EdgeAdmin/internal/web/actions/default/ui/components.go b/EdgeAdmin/internal/web/actions/default/ui/components.go
index 2c7dbfd..9decb16 100644
--- a/EdgeAdmin/internal/web/actions/default/ui/components.go
+++ b/EdgeAdmin/internal/web/actions/default/ui/components.go
@@ -16,6 +16,8 @@ import (
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
"net/http"
+ "os"
+ "path/filepath"
)
type ComponentsAction actions.Action
@@ -41,12 +43,7 @@ func (this *ComponentsAction) RunGet(params struct{}) {
var buffer = bytes.NewBuffer([]byte{})
- var webRoot string
- if Tea.IsTesting() {
- webRoot = Tea.Root + "/../web/public/js/components/"
- } else {
- webRoot = Tea.Root + "/web/public/js/components/"
- }
+ webRoot := findComponentsRoot()
f := files.NewFile(webRoot)
f.Range(func(file *files.File) {
@@ -173,3 +170,27 @@ func (this *ComponentsAction) RunGet(params struct{}) {
_, _ = this.Write(componentsData)
}
+
+func findComponentsRoot() string {
+ candidates := []string{
+ filepath.Join(Tea.Root, "web", "public", "js", "components"),
+ filepath.Join(Tea.Root, "..", "web", "public", "js", "components"),
+ filepath.Join(Tea.Root, "..", "..", "web", "public", "js", "components"),
+ }
+
+ if cwd, err := os.Getwd(); err == nil && len(cwd) > 0 {
+ candidates = append(candidates,
+ filepath.Join(cwd, "web", "public", "js", "components"),
+ filepath.Join(cwd, "EdgeAdmin", "web", "public", "js", "components"),
+ )
+ }
+
+ for _, candidate := range candidates {
+ info, err := os.Stat(candidate)
+ if err == nil && info.IsDir() {
+ return candidate + string(filepath.Separator)
+ }
+ }
+
+ return filepath.Join(Tea.Root, "web", "public", "js", "components") + string(filepath.Separator)
+}
diff --git a/EdgeAdmin/internal/web/import.go b/EdgeAdmin/internal/web/import.go
index 73167f8..79cc14f 100644
--- a/EdgeAdmin/internal/web/import.go
+++ b/EdgeAdmin/internal/web/import.go
@@ -141,7 +141,6 @@ import (
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/apps"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/clusters"
- _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/clusters"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/resolveLogs"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/runtimeLogs"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/sandbox"
diff --git a/EdgeAdmin/web/public/js/components.js b/EdgeAdmin/web/public/js/components.js
index e333e92..09b483a 100644
--- a/EdgeAdmin/web/public/js/components.js
+++ b/EdgeAdmin/web/public/js/components.js
@@ -2272,6 +2272,57 @@ Vue.component("health-check-config-box", {
`
})
+Vue.component("httpdns-clusters-selector", {
+ props: ["vClusters", "vName"],
+ data: function () {
+ let inputClusters = this.vClusters
+ let clusters = []
+
+ if (inputClusters != null && inputClusters.length > 0) {
+ if (inputClusters[0].isChecked !== undefined) {
+ // 带 isChecked 标志的完整集群列表
+ clusters = inputClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: c.isChecked}
+ })
+ } else {
+ // 仅包含已选集群,全部标记为选中
+ clusters = inputClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: true}
+ })
+ }
+ }
+
+ // 无 prop 时从根实例读取所有集群(如创建应用页面)
+ if (clusters.length === 0) {
+ let rootClusters = this.$root.clusters
+ if (rootClusters != null && rootClusters.length > 0) {
+ clusters = rootClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: false}
+ })
+ }
+ }
+
+ return {
+ clusters: clusters,
+ fieldName: this.vName || "clusterIds"
+ }
+ },
+ methods: {
+ changeCluster: function (cluster) {
+ cluster.isChecked = !cluster.isChecked
+ }
+ },
+ template: `
+
+
+ {{cluster.name}}
+
+
+
暂无可用集群
+
`
+})
+
+
/**
* 菜单项
*/
@@ -11294,10 +11345,18 @@ Vue.component("http-auth-config-box", {
if (authConfig.policyRefs == null) {
authConfig.policyRefs = []
}
- return {
+ return {
authConfig: authConfig
}
},
+ watch: {
+ "authConfig.isOn": function () {
+ this.change()
+ },
+ "authConfig.isPrior": function () {
+ this.change()
+ }
+ },
methods: {
isOn: function () {
return (!this.vIsLocation || this.authConfig.isPrior) && this.authConfig.isOn
@@ -11309,18 +11368,17 @@ Vue.component("http-auth-config-box", {
that.authConfig.policyRefs.push(resp.data.policyRef)
that.change()
},
- height: "28em"
+ height: "32em"
})
},
update: function (index, policyId) {
- let that = this
teaweb.popup("/servers/server/settings/access/updatePopup?policyId=" + policyId, {
- callback: function (resp) {
+ callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
},
- height: "28em"
+ height: "32em"
})
},
remove: function (index) {
@@ -11341,14 +11399,15 @@ Vue.component("http-auth-config-box", {
return "URL鉴权C"
case "typeD":
return "URL鉴权D"
+ case "typeE":
+ return "URL鉴权E"
}
return ""
},
change: function () {
let that = this
setTimeout(function () {
- // 延时通知,是为了让表单有机会变更数据
- that.$emit("change", this.authConfig)
+ that.$emit("change", that.authConfig)
}, 100)
}
},
@@ -11369,7 +11428,6 @@ Vue.component("http-auth-config-box", {
-
鉴权方式
@@ -11385,9 +11443,7 @@ Vue.component("http-auth-config-box", {
| {{ref.authPolicy.name}} |
-
- {{methodName(ref.authPolicy.type)}}
- |
+ {{methodName(ref.authPolicy.type)}} |
{{ref.authPolicy.params.users.length}}个用户
@@ -11398,7 +11454,7 @@ Vue.component("http-auth-config-box", {
有效期{{ref.authPolicy.params.life}}秒
有效期{{ref.authPolicy.params.life}}秒
{{ref.authPolicy.params.signParamName}}/{{ref.authPolicy.params.timestampParamName}}/有效期{{ref.authPolicy.params.life}}秒
-
+ 路径模式/有效期{{ref.authPolicy.params.life}}秒
扩展名:{{ext}}
域名:{{domain}}
@@ -11420,6 +11476,7 @@ Vue.component("http-auth-config-box", {
`
})
+
Vue.component("http-cache-config-box", {
props: ["v-cache-config", "v-is-location", "v-is-group", "v-cache-policy", "v-web-id"],
data: function () {
diff --git a/EdgeAdmin/web/public/js/components.src.js b/EdgeAdmin/web/public/js/components.src.js
index e333e92..09b483a 100644
--- a/EdgeAdmin/web/public/js/components.src.js
+++ b/EdgeAdmin/web/public/js/components.src.js
@@ -2272,6 +2272,57 @@ Vue.component("health-check-config-box", {
`
})
+Vue.component("httpdns-clusters-selector", {
+ props: ["vClusters", "vName"],
+ data: function () {
+ let inputClusters = this.vClusters
+ let clusters = []
+
+ if (inputClusters != null && inputClusters.length > 0) {
+ if (inputClusters[0].isChecked !== undefined) {
+ // 带 isChecked 标志的完整集群列表
+ clusters = inputClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: c.isChecked}
+ })
+ } else {
+ // 仅包含已选集群,全部标记为选中
+ clusters = inputClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: true}
+ })
+ }
+ }
+
+ // 无 prop 时从根实例读取所有集群(如创建应用页面)
+ if (clusters.length === 0) {
+ let rootClusters = this.$root.clusters
+ if (rootClusters != null && rootClusters.length > 0) {
+ clusters = rootClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: false}
+ })
+ }
+ }
+
+ return {
+ clusters: clusters,
+ fieldName: this.vName || "clusterIds"
+ }
+ },
+ methods: {
+ changeCluster: function (cluster) {
+ cluster.isChecked = !cluster.isChecked
+ }
+ },
+ template: `
+
+
+ {{cluster.name}}
+
+
+ 暂无可用集群
+ `
+})
+
+
/**
* 菜单项
*/
@@ -11294,10 +11345,18 @@ Vue.component("http-auth-config-box", {
if (authConfig.policyRefs == null) {
authConfig.policyRefs = []
}
- return {
+ return {
authConfig: authConfig
}
},
+ watch: {
+ "authConfig.isOn": function () {
+ this.change()
+ },
+ "authConfig.isPrior": function () {
+ this.change()
+ }
+ },
methods: {
isOn: function () {
return (!this.vIsLocation || this.authConfig.isPrior) && this.authConfig.isOn
@@ -11309,18 +11368,17 @@ Vue.component("http-auth-config-box", {
that.authConfig.policyRefs.push(resp.data.policyRef)
that.change()
},
- height: "28em"
+ height: "32em"
})
},
update: function (index, policyId) {
- let that = this
teaweb.popup("/servers/server/settings/access/updatePopup?policyId=" + policyId, {
- callback: function (resp) {
+ callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
},
- height: "28em"
+ height: "32em"
})
},
remove: function (index) {
@@ -11341,14 +11399,15 @@ Vue.component("http-auth-config-box", {
return "URL鉴权C"
case "typeD":
return "URL鉴权D"
+ case "typeE":
+ return "URL鉴权E"
}
return ""
},
change: function () {
let that = this
setTimeout(function () {
- // 延时通知,是为了让表单有机会变更数据
- that.$emit("change", this.authConfig)
+ that.$emit("change", that.authConfig)
}, 100)
}
},
@@ -11369,7 +11428,6 @@ Vue.component("http-auth-config-box", {
|
-
鉴权方式
@@ -11385,9 +11443,7 @@ Vue.component("http-auth-config-box", {
| {{ref.authPolicy.name}} |
-
- {{methodName(ref.authPolicy.type)}}
- |
+ {{methodName(ref.authPolicy.type)}} |
{{ref.authPolicy.params.users.length}}个用户
@@ -11398,7 +11454,7 @@ Vue.component("http-auth-config-box", {
有效期{{ref.authPolicy.params.life}}秒
有效期{{ref.authPolicy.params.life}}秒
{{ref.authPolicy.params.signParamName}}/{{ref.authPolicy.params.timestampParamName}}/有效期{{ref.authPolicy.params.life}}秒
-
+ 路径模式/有效期{{ref.authPolicy.params.life}}秒
扩展名:{{ext}}
域名:{{domain}}
@@ -11420,6 +11476,7 @@ Vue.component("http-auth-config-box", {
`
})
+
Vue.component("http-cache-config-box", {
props: ["v-cache-config", "v-is-location", "v-is-group", "v-cache-policy", "v-web-id"],
data: function () {
diff --git a/EdgeAdmin/web/public/js/components/common/httpdns-clusters-selector.js b/EdgeAdmin/web/public/js/components/common/httpdns-clusters-selector.js
new file mode 100644
index 0000000..0c4d0d5
--- /dev/null
+++ b/EdgeAdmin/web/public/js/components/common/httpdns-clusters-selector.js
@@ -0,0 +1,49 @@
+Vue.component("httpdns-clusters-selector", {
+ props: ["vClusters", "vName"],
+ data: function () {
+ let inputClusters = this.vClusters
+ let clusters = []
+
+ if (inputClusters != null && inputClusters.length > 0) {
+ if (inputClusters[0].isChecked !== undefined) {
+ // 带 isChecked 标志的完整集群列表
+ clusters = inputClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: c.isChecked}
+ })
+ } else {
+ // 仅包含已选集群,全部标记为选中
+ clusters = inputClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: true}
+ })
+ }
+ }
+
+ // 无 prop 时从根实例读取所有集群(如创建应用页面)
+ if (clusters.length === 0) {
+ let rootClusters = this.$root.clusters
+ if (rootClusters != null && rootClusters.length > 0) {
+ clusters = rootClusters.map(function (c) {
+ return {id: c.id, name: c.name, isChecked: false}
+ })
+ }
+ }
+
+ return {
+ clusters: clusters,
+ fieldName: this.vName || "clusterIds"
+ }
+ },
+ methods: {
+ changeCluster: function (cluster) {
+ cluster.isChecked = !cluster.isChecked
+ }
+ },
+ template: `
+
+
+ {{cluster.name}}
+
+
+ 暂无可用集群
+ `
+})
diff --git a/EdgeAdmin/web/public/js/components/server/http-auth-config-box.js b/EdgeAdmin/web/public/js/components/server/http-auth-config-box.js
index 02a5487..75f513c 100644
--- a/EdgeAdmin/web/public/js/components/server/http-auth-config-box.js
+++ b/EdgeAdmin/web/public/js/components/server/http-auth-config-box.js
@@ -12,10 +12,18 @@ Vue.component("http-auth-config-box", {
if (authConfig.policyRefs == null) {
authConfig.policyRefs = []
}
- return {
+ return {
authConfig: authConfig
}
},
+ watch: {
+ "authConfig.isOn": function () {
+ this.change()
+ },
+ "authConfig.isPrior": function () {
+ this.change()
+ }
+ },
methods: {
isOn: function () {
return (!this.vIsLocation || this.authConfig.isPrior) && this.authConfig.isOn
@@ -27,18 +35,17 @@ Vue.component("http-auth-config-box", {
that.authConfig.policyRefs.push(resp.data.policyRef)
that.change()
},
- height: "28em"
+ height: "32em"
})
},
update: function (index, policyId) {
- let that = this
teaweb.popup("/servers/server/settings/access/updatePopup?policyId=" + policyId, {
- callback: function (resp) {
+ callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()
})
},
- height: "28em"
+ height: "32em"
})
},
remove: function (index) {
@@ -59,14 +66,15 @@ Vue.component("http-auth-config-box", {
return "URL鉴权C"
case "typeD":
return "URL鉴权D"
+ case "typeE":
+ return "URL鉴权E"
}
return ""
},
change: function () {
let that = this
setTimeout(function () {
- // 延时通知,是为了让表单有机会变更数据
- that.$emit("change", this.authConfig)
+ that.$emit("change", that.authConfig)
}, 100)
}
},
@@ -87,7 +95,6 @@ Vue.component("http-auth-config-box", {
|
-
鉴权方式
@@ -103,9 +110,7 @@ Vue.component("http-auth-config-box", {
| {{ref.authPolicy.name}} |
-
- {{methodName(ref.authPolicy.type)}}
- |
+ {{methodName(ref.authPolicy.type)}} |
{{ref.authPolicy.params.users.length}}个用户
@@ -116,7 +121,7 @@ Vue.component("http-auth-config-box", {
有效期{{ref.authPolicy.params.life}}秒
有效期{{ref.authPolicy.params.life}}秒
{{ref.authPolicy.params.signParamName}}/{{ref.authPolicy.params.timestampParamName}}/有效期{{ref.authPolicy.params.life}}秒
-
+ 路径模式/有效期{{ref.authPolicy.params.life}}秒
扩展名:{{ext}}
域名:{{domain}}
@@ -136,4 +141,4 @@ Vue.component("http-auth-config-box", {
`
-})
\ No newline at end of file
+})
diff --git a/EdgeAdmin/web/views/@default/@layout.html b/EdgeAdmin/web/views/@default/@layout.html
index 722a93c..837c78c 100644
--- a/EdgeAdmin/web/views/@default/@layout.html
+++ b/EdgeAdmin/web/views/@default/@layout.html
@@ -37,7 +37,7 @@
-
+
diff --git a/EdgeAdmin/web/views/@default/clusters/cluster/settings/network-security/index.html b/EdgeAdmin/web/views/@default/clusters/cluster/settings/network-security/index.html
deleted file mode 100644
index c5e03ba..0000000
--- a/EdgeAdmin/web/views/@default/clusters/cluster/settings/network-security/index.html
+++ /dev/null
@@ -1,32 +0,0 @@
-{$layout}
-
-{$template "../menu"}
-{$template "/left_menu_with_menu"}
-
-
\ No newline at end of file
diff --git a/EdgeAdmin/web/views/@default/clusters/cluster/settings/network-security/index.js b/EdgeAdmin/web/views/@default/clusters/cluster/settings/network-security/index.js
deleted file mode 100644
index 295a9aa..0000000
--- a/EdgeAdmin/web/views/@default/clusters/cluster/settings/network-security/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-Tea.context(function () {
- this.success = NotifyReloadSuccess("保存成功")
-})
\ No newline at end of file
diff --git a/EdgeAdmin/web/views/@default/dashboard/boards/@menu.html b/EdgeAdmin/web/views/@default/dashboard/boards/@menu.html
index d9ac6ff..cb5de8d 100644
--- a/EdgeAdmin/web/views/@default/dashboard/boards/@menu.html
+++ b/EdgeAdmin/web/views/@default/dashboard/boards/@menu.html
@@ -6,6 +6,7 @@
({{countTodayAttacksFormat}})
{{LANG('admin_dashboard@ui_dns')}}
+ HTTPDNS
{{LANG('admin_dashboard@ui_user')}}
{{LANG('admin_dashboard@ui_events')}}({{countEvents}})
-
\ No newline at end of file
+
diff --git a/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.css b/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.css
new file mode 100644
index 0000000..660af90
--- /dev/null
+++ b/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.css
@@ -0,0 +1,8 @@
+.ui.message .icon {
+ position: absolute;
+ right: 1em;
+ top: 1.8em;
+}
+.chart-box {
+ height: 14em;
+}
diff --git a/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.html b/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.html
new file mode 100644
index 0000000..50bc8cc
--- /dev/null
+++ b/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.html
@@ -0,0 +1,67 @@
+{$layout}
+{$template "menu"}
+{$template "/echarts"}
+
+
+
+
+
+
+ 应用
+ {{board.countApps}}个
+
+
+ 域名
+ {{board.countDomains}}个
+
+
+ 集群
+ {{board.countClusters}}个
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.js b/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.js
new file mode 100644
index 0000000..2cf6eb7
--- /dev/null
+++ b/EdgeAdmin/web/views/@default/dashboard/boards/httpdns.js
@@ -0,0 +1,192 @@
+Tea.context(function () {
+ this.isLoading = true
+
+ this.$delay(function () {
+ this.$post("$")
+ .success(function (resp) {
+ for (let k in resp.data) {
+ this[k] = resp.data[k]
+ }
+
+ this.$delay(function () {
+ this.reloadHourlyTrafficChart()
+ this.reloadTopAppsChart()
+ this.reloadTopDomainsChart()
+ this.reloadTopNodesChart()
+ })
+
+ this.isLoading = false
+ })
+ })
+
+ this.trafficTab = "hourly"
+
+ this.selectTrafficTab = function (tab) {
+ this.trafficTab = tab
+ if (tab == "hourly") {
+ this.$delay(function () {
+ this.reloadHourlyTrafficChart()
+ })
+ } else if (tab == "daily") {
+ this.$delay(function () {
+ this.reloadDailyTrafficChart()
+ })
+ }
+ }
+
+ this.reloadHourlyTrafficChart = function () {
+ let stats = this.hourlyStats
+ if (stats == null || stats.length == 0) {
+ return
+ }
+ this.reloadTrafficChart("hourly-traffic-chart", stats, function (args) {
+ return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ })
+ }
+
+ this.reloadDailyTrafficChart = function () {
+ let stats = this.dailyStats
+ if (stats == null || stats.length == 0) {
+ return
+ }
+ this.reloadTrafficChart("daily-traffic-chart", stats, function (args) {
+ return stats[args.dataIndex].day + " 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ })
+ }
+
+ this.reloadTrafficChart = function (chartId, stats, tooltipFunc) {
+ let chartBox = document.getElementById(chartId)
+ if (chartBox == null) {
+ return
+ }
+
+ let axis = teaweb.countAxis(stats, function (v) {
+ return v.countRequests
+ })
+
+ let chart = teaweb.initChart(chartBox)
+ let option = {
+ xAxis: {
+ data: stats.map(function (v) {
+ if (v.hour != null) {
+ return v.hour
+ }
+ return v.day
+ })
+ },
+ yAxis: {
+ axisLabel: {
+ formatter: function (value) {
+ return value + axis.unit
+ }
+ }
+ },
+ tooltip: {
+ show: true,
+ trigger: "item",
+ formatter: tooltipFunc
+ },
+ grid: {
+ left: 50,
+ top: 10,
+ right: 20,
+ bottom: 20
+ },
+ series: [
+ {
+ name: "请求数",
+ type: "line",
+ data: stats.map(function (v) {
+ return v.countRequests / axis.divider
+ }),
+ itemStyle: {
+ color: teaweb.DefaultChartColor
+ },
+ areaStyle: {
+ color: teaweb.DefaultChartColor
+ },
+ smooth: true
+ }
+ ],
+ animation: true
+ }
+ chart.setOption(option)
+ chart.resize()
+ }
+
+ this.reloadTopAppsChart = function () {
+ if (this.topAppStats == null || this.topAppStats.length == 0) {
+ return
+ }
+ let axis = teaweb.countAxis(this.topAppStats, function (v) {
+ return v.countRequests
+ })
+ teaweb.renderBarChart({
+ id: "top-apps-chart",
+ name: "应用",
+ values: this.topAppStats,
+ x: function (v) {
+ return v.appName
+ },
+ tooltip: function (args, stats) {
+ return stats[args.dataIndex].appName + " 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ },
+ value: function (v) {
+ return v.countRequests / axis.divider
+ },
+ axis: axis
+ })
+ }
+
+ this.reloadTopDomainsChart = function () {
+ if (this.topDomainStats == null || this.topDomainStats.length == 0) {
+ return
+ }
+ let axis = teaweb.countAxis(this.topDomainStats, function (v) {
+ return v.countRequests
+ })
+ teaweb.renderBarChart({
+ id: "top-domains-chart",
+ name: "域名",
+ values: this.topDomainStats,
+ x: function (v) {
+ return v.domainName
+ },
+ tooltip: function (args, stats) {
+ return stats[args.dataIndex].domainName + " 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ },
+ value: function (v) {
+ return v.countRequests / axis.divider
+ },
+ axis: axis
+ })
+ }
+
+ this.reloadTopNodesChart = function () {
+ if (this.topNodeStats == null || this.topNodeStats.length == 0) {
+ return
+ }
+ let axis = teaweb.countAxis(this.topNodeStats, function (v) {
+ return v.countRequests
+ })
+ teaweb.renderBarChart({
+ id: "top-nodes-chart",
+ name: "节点",
+ values: this.topNodeStats,
+ x: function (v) {
+ return v.nodeName
+ },
+ tooltip: function (args, stats) {
+ return stats[args.dataIndex].nodeName + " 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ },
+ value: function (v) {
+ return v.countRequests / axis.divider
+ },
+ axis: axis,
+ click: function (args, stats) {
+ window.location = "/httpdns/clusters/cluster/node?nodeId=" + stats[args.dataIndex].nodeId + "&clusterId=" + stats[args.dataIndex].clusterId
+ }
+ })
+ }
+
+})
diff --git a/EdgeAdmin/web/views/@default/dashboard/boards/index.html b/EdgeAdmin/web/views/@default/dashboard/boards/index.html
index cc67d25..ffb0475 100644
--- a/EdgeAdmin/web/views/@default/dashboard/boards/index.html
+++ b/EdgeAdmin/web/views/@default/dashboard/boards/index.html
@@ -53,8 +53,9 @@
@@ -73,7 +74,15 @@
+
diff --git a/EdgeAdmin/web/views/@default/dashboard/index.html b/EdgeAdmin/web/views/@default/dashboard/index.html
index f79e5f9..0697ee7 100644
--- a/EdgeAdmin/web/views/@default/dashboard/index.html
+++ b/EdgeAdmin/web/views/@default/dashboard/index.html
@@ -33,7 +33,9 @@
diff --git a/EdgeAdmin/web/views/@default/httpdns/clusters/create.js b/EdgeAdmin/web/views/@default/httpdns/clusters/create.js
index 0918023..8234e7c 100644
--- a/EdgeAdmin/web/views/@default/httpdns/clusters/create.js
+++ b/EdgeAdmin/web/views/@default/httpdns/clusters/create.js
@@ -1,6 +1,9 @@
Tea.context(function () {
this.isOn = true
+ this.syncDefaultClusterEnabled = function () {
+ }
+
this.success = function (resp) {
let clusterId = 0
if (resp != null && resp.data != null && typeof resp.data.clusterId != "undefined") {
diff --git a/EdgeAdmin/web/views/@default/httpdns/index.css b/EdgeAdmin/web/views/@default/httpdns/index.css
new file mode 100644
index 0000000..660af90
--- /dev/null
+++ b/EdgeAdmin/web/views/@default/httpdns/index.css
@@ -0,0 +1,8 @@
+.ui.message .icon {
+ position: absolute;
+ right: 1em;
+ top: 1.8em;
+}
+.chart-box {
+ height: 14em;
+}
diff --git a/EdgeAdmin/web/views/@default/httpdns/index.html b/EdgeAdmin/web/views/@default/httpdns/index.html
new file mode 100644
index 0000000..2f234a2
--- /dev/null
+++ b/EdgeAdmin/web/views/@default/httpdns/index.html
@@ -0,0 +1,62 @@
+{$layout}
+{$template "/echarts"}
+
+
+
+
+
+
+ 应用
+ {{board.countApps}}个
+
+
+ 域名
+ {{board.countDomains}}个
+
+
+ 集群
+ {{board.countClusters}}个
+
+
+ 节点
+ {{board.countNodes}}
+ {{board.countOfflineNodes}}离线
+ 个
+
+
+
+
+
+
diff --git a/EdgeAdmin/web/views/@default/httpdns/index.js b/EdgeAdmin/web/views/@default/httpdns/index.js
new file mode 100644
index 0000000..c7d2ede
--- /dev/null
+++ b/EdgeAdmin/web/views/@default/httpdns/index.js
@@ -0,0 +1,191 @@
+Tea.context(function () {
+ this.isLoading = true
+
+ this.$delay(function () {
+ this.$post("$")
+ .success(function (resp) {
+ for (let k in resp.data) {
+ this[k] = resp.data[k]
+ }
+
+ this.$delay(function () {
+ this.reloadHourlyTrafficChart()
+ this.reloadTopAppsChart()
+ this.reloadTopDomainsChart()
+ this.reloadTopNodesChart()
+ })
+
+ this.isLoading = false
+ })
+ })
+
+ this.trafficTab = "hourly"
+
+ this.selectTrafficTab = function (tab) {
+ this.trafficTab = tab
+ if (tab == "hourly") {
+ this.$delay(function () {
+ this.reloadHourlyTrafficChart()
+ })
+ } else if (tab == "daily") {
+ this.$delay(function () {
+ this.reloadDailyTrafficChart()
+ })
+ }
+ }
+
+ this.reloadHourlyTrafficChart = function () {
+ let stats = this.hourlyStats
+ if (stats == null || stats.length == 0) {
+ return
+ }
+ this.reloadTrafficChart("hourly-traffic-chart", stats, function (args) {
+ return stats[args.dataIndex].day + " " + stats[args.dataIndex].hour + "时 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ })
+ }
+
+ this.reloadDailyTrafficChart = function () {
+ let stats = this.dailyStats
+ if (stats == null || stats.length == 0) {
+ return
+ }
+ this.reloadTrafficChart("daily-traffic-chart", stats, function (args) {
+ return stats[args.dataIndex].day + " 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ })
+ }
+
+ this.reloadTrafficChart = function (chartId, stats, tooltipFunc) {
+ let chartBox = document.getElementById(chartId)
+ if (chartBox == null) {
+ return
+ }
+
+ let axis = teaweb.countAxis(stats, function (v) {
+ return v.countRequests
+ })
+
+ let chart = teaweb.initChart(chartBox)
+ let option = {
+ xAxis: {
+ data: stats.map(function (v) {
+ if (v.hour != null) {
+ return v.hour
+ }
+ return v.day
+ })
+ },
+ yAxis: {
+ axisLabel: {
+ formatter: function (value) {
+ return value + axis.unit
+ }
+ }
+ },
+ tooltip: {
+ show: true,
+ trigger: "item",
+ formatter: tooltipFunc
+ },
+ grid: {
+ left: 50,
+ top: 10,
+ right: 20,
+ bottom: 20
+ },
+ series: [
+ {
+ name: "请求数",
+ type: "line",
+ data: stats.map(function (v) {
+ return v.countRequests / axis.divider
+ }),
+ itemStyle: {
+ color: teaweb.DefaultChartColor
+ },
+ areaStyle: {
+ color: teaweb.DefaultChartColor
+ },
+ smooth: true
+ }
+ ],
+ animation: true
+ }
+ chart.setOption(option)
+ chart.resize()
+ }
+
+ this.reloadTopAppsChart = function () {
+ if (this.topAppStats == null || this.topAppStats.length == 0) {
+ return
+ }
+ let axis = teaweb.countAxis(this.topAppStats, function (v) {
+ return v.countRequests
+ })
+ teaweb.renderBarChart({
+ id: "top-apps-chart",
+ name: "应用",
+ values: this.topAppStats,
+ x: function (v) {
+ return v.appName
+ },
+ tooltip: function (args, stats) {
+ return stats[args.dataIndex].appName + " 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ },
+ value: function (v) {
+ return v.countRequests / axis.divider
+ },
+ axis: axis
+ })
+ }
+
+ this.reloadTopDomainsChart = function () {
+ if (this.topDomainStats == null || this.topDomainStats.length == 0) {
+ return
+ }
+ let axis = teaweb.countAxis(this.topDomainStats, function (v) {
+ return v.countRequests
+ })
+ teaweb.renderBarChart({
+ id: "top-domains-chart",
+ name: "域名",
+ values: this.topDomainStats,
+ x: function (v) {
+ return v.domainName
+ },
+ tooltip: function (args, stats) {
+ return stats[args.dataIndex].domainName + " 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ },
+ value: function (v) {
+ return v.countRequests / axis.divider
+ },
+ axis: axis
+ })
+ }
+
+ this.reloadTopNodesChart = function () {
+ if (this.topNodeStats == null || this.topNodeStats.length == 0) {
+ return
+ }
+ let axis = teaweb.countAxis(this.topNodeStats, function (v) {
+ return v.countRequests
+ })
+ teaweb.renderBarChart({
+ id: "top-nodes-chart",
+ name: "节点",
+ values: this.topNodeStats,
+ x: function (v) {
+ return v.nodeName
+ },
+ tooltip: function (args, stats) {
+ return stats[args.dataIndex].nodeName + " 请求数:" + teaweb.formatNumber(stats[args.dataIndex].countRequests)
+ },
+ value: function (v) {
+ return v.countRequests / axis.divider
+ },
+ axis: axis,
+ click: function (args, stats) {
+ window.location = "/httpdns/clusters/cluster/node?nodeId=" + stats[args.dataIndex].nodeId + "&clusterId=" + stats[args.dataIndex].clusterId
+ }
+ })
+ }
+})
diff --git a/EdgeAdmin/web/views/@default/servers/server/settings/access/createPopup.html b/EdgeAdmin/web/views/@default/servers/server/settings/access/createPopup.html
index 413d08e..55028b3 100644
--- a/EdgeAdmin/web/views/@default/servers/server/settings/access/createPopup.html
+++ b/EdgeAdmin/web/views/@default/servers/server/settings/access/createPopup.html
@@ -124,6 +124,27 @@
|
+
+
+
+ | 鉴权密钥 * |
+
+
+
+ |
+
+
+ | 有效时间 |
+
+
+
+ 秒
+
+
+ |
+
+
+
@@ -138,7 +159,7 @@
- | 认证领域名(Realm) |
+ 认证领域名 (Realm) |
|
@@ -147,7 +168,7 @@
字符集 |
-
+
|
@@ -186,7 +207,7 @@
限定文件扩展名 |
-
+
|
@@ -200,4 +221,4 @@
-
\ No newline at end of file
+
diff --git a/EdgeAdmin/web/views/@default/servers/server/settings/access/createPopup.js b/EdgeAdmin/web/views/@default/servers/server/settings/access/createPopup.js
index 93c9905..9216c7f 100644
--- a/EdgeAdmin/web/views/@default/servers/server/settings/access/createPopup.js
+++ b/EdgeAdmin/web/views/@default/servers/server/settings/access/createPopup.js
@@ -84,6 +84,18 @@ Tea.context(function () {
this.authDescription = this.authDescription.replace("t=", this.typeDTimestampParamName + "=")
}
+ /**
+ * TypeE
+ */
+ this.typeESecret = ""
+
+ this.generateTypeESecret = function () {
+ this.$post(".random")
+ .success(function (resp) {
+ this.typeESecret = resp.data.random
+ })
+ }
+
/**
* 基本认证
*/
@@ -97,4 +109,4 @@ Tea.context(function () {
* 子请求
*/
this.subRequestFollowRequest = 1
-})
\ No newline at end of file
+})
diff --git a/EdgeAdmin/web/views/@default/servers/server/settings/access/updatePopup.html b/EdgeAdmin/web/views/@default/servers/server/settings/access/updatePopup.html
index 7b4f98a..17bb03d 100644
--- a/EdgeAdmin/web/views/@default/servers/server/settings/access/updatePopup.html
+++ b/EdgeAdmin/web/views/@default/servers/server/settings/access/updatePopup.html
@@ -122,6 +122,27 @@
+
+
+
+ | 鉴权密钥 * |
+
+
+
+ |
+
+
+ | 有效时间 |
+
+
+
+ 秒
+
+
+ |
+
+
+
@@ -136,7 +157,7 @@
- | 认证领域名(Realm) |
+ 认证领域名 (Realm) |
|
@@ -145,7 +166,7 @@
字符集 |
-
+
|
@@ -185,7 +206,7 @@
限定文件扩展名 |
-
+
|
@@ -203,4 +224,4 @@
-
\ No newline at end of file
+
diff --git a/EdgeAdmin/web/views/@default/servers/server/settings/access/updatePopup.js b/EdgeAdmin/web/views/@default/servers/server/settings/access/updatePopup.js
index 8891308..365a308 100644
--- a/EdgeAdmin/web/views/@default/servers/server/settings/access/updatePopup.js
+++ b/EdgeAdmin/web/views/@default/servers/server/settings/access/updatePopup.js
@@ -115,6 +115,22 @@ Tea.context(function () {
this.authDescription = this.authDescription.replace("t=", this.typeDTimestampParamName + "=")
}
+ /**
+ * TypeE
+ */
+ this.typeESecret = ""
+
+ if (this.policy.type == "typeE") {
+ this.typeESecret = this.policy.params.secret
+ }
+
+ this.generateTypeESecret = function () {
+ this.$post(".random")
+ .success(function (resp) {
+ this.typeESecret = resp.data.random
+ })
+ }
+
/**
* 基本鉴权
*/
@@ -128,4 +144,4 @@ Tea.context(function () {
* 子请求
*/
this.subRequestFollowRequest = (this.policy.params.method != null && this.policy.params.method.length > 0) ? 0 : 1
-})
\ No newline at end of file
+})
diff --git a/EdgeCommon/.gitignore b/EdgeCommon/.gitignore
index e69de29..a12dacd 100644
--- a/EdgeCommon/.gitignore
+++ b/EdgeCommon/.gitignore
@@ -0,0 +1 @@
+build/temp_build.sh
diff --git a/EdgeCommon/build/rpc.json b/EdgeCommon/build/rpc.json
index d43ae82..87d8b81 100644
--- a/EdgeCommon/build/rpc.json
+++ b/EdgeCommon/build/rpc.json
@@ -3682,6 +3682,564 @@
"filename": "service_http_websocket.proto",
"doc": "HTTP Websocket管理服务"
},
+ {
+ "name": "HTTPDNSAccessLogService",
+ "methods": [
+ {
+ "name": "createHTTPDNSAccessLogs",
+ "requestMessageName": "CreateHTTPDNSAccessLogsRequest",
+ "responseMessageName": "CreateHTTPDNSAccessLogsResponse",
+ "code": "rpc createHTTPDNSAccessLogs (CreateHTTPDNSAccessLogsRequest) returns (CreateHTTPDNSAccessLogsResponse);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "listHTTPDNSAccessLogs",
+ "requestMessageName": "ListHTTPDNSAccessLogsRequest",
+ "responseMessageName": "ListHTTPDNSAccessLogsResponse",
+ "code": "rpc listHTTPDNSAccessLogs (ListHTTPDNSAccessLogsRequest) returns (ListHTTPDNSAccessLogsResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_access_log.proto",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSAppService",
+ "methods": [
+ {
+ "name": "createHTTPDNSApp",
+ "requestMessageName": "CreateHTTPDNSAppRequest",
+ "responseMessageName": "CreateHTTPDNSAppResponse",
+ "code": "rpc createHTTPDNSApp (CreateHTTPDNSAppRequest) returns (CreateHTTPDNSAppResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSApp",
+ "requestMessageName": "UpdateHTTPDNSAppRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSApp (UpdateHTTPDNSAppRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "deleteHTTPDNSApp",
+ "requestMessageName": "DeleteHTTPDNSAppRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc deleteHTTPDNSApp (DeleteHTTPDNSAppRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "findHTTPDNSApp",
+ "requestMessageName": "FindHTTPDNSAppRequest",
+ "responseMessageName": "FindHTTPDNSAppResponse",
+ "code": "rpc findHTTPDNSApp (FindHTTPDNSAppRequest) returns (FindHTTPDNSAppResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "listHTTPDNSApps",
+ "requestMessageName": "ListHTTPDNSAppsRequest",
+ "responseMessageName": "ListHTTPDNSAppsResponse",
+ "code": "rpc listHTTPDNSApps (ListHTTPDNSAppsRequest) returns (ListHTTPDNSAppsResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "findAllHTTPDNSApps",
+ "requestMessageName": "FindAllHTTPDNSAppsRequest",
+ "responseMessageName": "FindAllHTTPDNSAppsResponse",
+ "code": "rpc findAllHTTPDNSApps (FindAllHTTPDNSAppsRequest) returns (FindAllHTTPDNSAppsResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSAppSignEnabled",
+ "requestMessageName": "UpdateHTTPDNSAppSignEnabledRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSAppSignEnabled (UpdateHTTPDNSAppSignEnabledRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "resetHTTPDNSAppSignSecret",
+ "requestMessageName": "ResetHTTPDNSAppSignSecretRequest",
+ "responseMessageName": "ResetHTTPDNSAppSignSecretResponse",
+ "code": "rpc resetHTTPDNSAppSignSecret (ResetHTTPDNSAppSignSecretRequest) returns (ResetHTTPDNSAppSignSecretResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_app.proto",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSBoardService",
+ "methods": [
+ {
+ "name": "composeHTTPDNSBoard",
+ "requestMessageName": "ComposeHTTPDNSBoardRequest",
+ "responseMessageName": "ComposeHTTPDNSBoardResponse",
+ "code": "rpc composeHTTPDNSBoard (ComposeHTTPDNSBoardRequest) returns (ComposeHTTPDNSBoardResponse);",
+ "doc": "组合看板数据",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_board.proto",
+ "doc": "HTTPDNS 看板服务"
+ },
+ {
+ "name": "HTTPDNSClusterService",
+ "methods": [
+ {
+ "name": "createHTTPDNSCluster",
+ "requestMessageName": "CreateHTTPDNSClusterRequest",
+ "responseMessageName": "CreateHTTPDNSClusterResponse",
+ "code": "rpc createHTTPDNSCluster (CreateHTTPDNSClusterRequest) returns (CreateHTTPDNSClusterResponse);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSCluster",
+ "requestMessageName": "UpdateHTTPDNSClusterRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSCluster (UpdateHTTPDNSClusterRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "deleteHTTPDNSCluster",
+ "requestMessageName": "DeleteHTTPDNSClusterRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc deleteHTTPDNSCluster (DeleteHTTPDNSClusterRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "findHTTPDNSCluster",
+ "requestMessageName": "FindHTTPDNSClusterRequest",
+ "responseMessageName": "FindHTTPDNSClusterResponse",
+ "code": "rpc findHTTPDNSCluster (FindHTTPDNSClusterRequest) returns (FindHTTPDNSClusterResponse);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "listHTTPDNSClusters",
+ "requestMessageName": "ListHTTPDNSClustersRequest",
+ "responseMessageName": "ListHTTPDNSClustersResponse",
+ "code": "rpc listHTTPDNSClusters (ListHTTPDNSClustersRequest) returns (ListHTTPDNSClustersResponse);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "findAllHTTPDNSClusters",
+ "requestMessageName": "FindAllHTTPDNSClustersRequest",
+ "responseMessageName": "FindAllHTTPDNSClustersResponse",
+ "code": "rpc findAllHTTPDNSClusters (FindAllHTTPDNSClustersRequest) returns (FindAllHTTPDNSClustersResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSClusterDefault",
+ "requestMessageName": "UpdateHTTPDNSClusterDefaultRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSClusterDefault (UpdateHTTPDNSClusterDefaultRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "listHTTPDNSNodesWithClusterId",
+ "requestMessageName": "ListHTTPDNSNodesWithClusterIdRequest",
+ "responseMessageName": "ListHTTPDNSNodesWithClusterIdResponse",
+ "code": "rpc listHTTPDNSNodesWithClusterId (ListHTTPDNSNodesWithClusterIdRequest) returns (ListHTTPDNSNodesWithClusterIdResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_cluster.proto",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSDomainService",
+ "methods": [
+ {
+ "name": "createHTTPDNSDomain",
+ "requestMessageName": "CreateHTTPDNSDomainRequest",
+ "responseMessageName": "CreateHTTPDNSDomainResponse",
+ "code": "rpc createHTTPDNSDomain (CreateHTTPDNSDomainRequest) returns (CreateHTTPDNSDomainResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "deleteHTTPDNSDomain",
+ "requestMessageName": "DeleteHTTPDNSDomainRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc deleteHTTPDNSDomain (DeleteHTTPDNSDomainRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSDomainStatus",
+ "requestMessageName": "UpdateHTTPDNSDomainStatusRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSDomainStatus (UpdateHTTPDNSDomainStatusRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "listHTTPDNSDomainsWithAppId",
+ "requestMessageName": "ListHTTPDNSDomainsWithAppIdRequest",
+ "responseMessageName": "ListHTTPDNSDomainsWithAppIdResponse",
+ "code": "rpc listHTTPDNSDomainsWithAppId (ListHTTPDNSDomainsWithAppIdRequest) returns (ListHTTPDNSDomainsWithAppIdResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_domain.proto",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSNodeService",
+ "methods": [
+ {
+ "name": "createHTTPDNSNode",
+ "requestMessageName": "CreateHTTPDNSNodeRequest",
+ "responseMessageName": "CreateHTTPDNSNodeResponse",
+ "code": "rpc createHTTPDNSNode (CreateHTTPDNSNodeRequest) returns (CreateHTTPDNSNodeResponse);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSNode",
+ "requestMessageName": "UpdateHTTPDNSNodeRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSNode (UpdateHTTPDNSNodeRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "deleteHTTPDNSNode",
+ "requestMessageName": "DeleteHTTPDNSNodeRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc deleteHTTPDNSNode (DeleteHTTPDNSNodeRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "findHTTPDNSNode",
+ "requestMessageName": "FindHTTPDNSNodeRequest",
+ "responseMessageName": "FindHTTPDNSNodeResponse",
+ "code": "rpc findHTTPDNSNode (FindHTTPDNSNodeRequest) returns (FindHTTPDNSNodeResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "listHTTPDNSNodes",
+ "requestMessageName": "ListHTTPDNSNodesRequest",
+ "responseMessageName": "ListHTTPDNSNodesResponse",
+ "code": "rpc listHTTPDNSNodes (ListHTTPDNSNodesRequest) returns (ListHTTPDNSNodesResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSNodeStatus",
+ "requestMessageName": "UpdateHTTPDNSNodeStatusRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSNodeStatus (UpdateHTTPDNSNodeStatusRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSNodeLogin",
+ "requestMessageName": "UpdateHTTPDNSNodeLoginRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSNodeLogin (UpdateHTTPDNSNodeLoginRequest) returns (RPCSuccess);",
+ "doc": "修改HTTPDNS节点登录信息",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "checkHTTPDNSNodeLatestVersion",
+ "requestMessageName": "CheckHTTPDNSNodeLatestVersionRequest",
+ "responseMessageName": "CheckHTTPDNSNodeLatestVersionResponse",
+ "code": "rpc checkHTTPDNSNodeLatestVersion (CheckHTTPDNSNodeLatestVersionRequest) returns (CheckHTTPDNSNodeLatestVersionResponse);",
+ "doc": "检查HTTPDNS节点新版本",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "downloadHTTPDNSNodeInstallationFile",
+ "requestMessageName": "DownloadHTTPDNSNodeInstallationFileRequest",
+ "responseMessageName": "DownloadHTTPDNSNodeInstallationFileResponse",
+ "code": "rpc downloadHTTPDNSNodeInstallationFile (DownloadHTTPDNSNodeInstallationFileRequest) returns (DownloadHTTPDNSNodeInstallationFileResponse);",
+ "doc": "下载最新HTTPDNS节点安装文件",
+ "roles": [],
+ "isDeprecated": false
+ },
+ {
+ "name": "countAllUpgradeHTTPDNSNodesWithClusterId",
+ "requestMessageName": "CountAllUpgradeHTTPDNSNodesWithClusterIdRequest",
+ "responseMessageName": "RPCCountResponse",
+ "code": "rpc countAllUpgradeHTTPDNSNodesWithClusterId (CountAllUpgradeHTTPDNSNodesWithClusterIdRequest) returns (RPCCountResponse);",
+ "doc": "计算需要升级的HTTPDNS节点数量",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "findAllUpgradeHTTPDNSNodesWithClusterId",
+ "requestMessageName": "FindAllUpgradeHTTPDNSNodesWithClusterIdRequest",
+ "responseMessageName": "FindAllUpgradeHTTPDNSNodesWithClusterIdResponse",
+ "code": "rpc findAllUpgradeHTTPDNSNodesWithClusterId (FindAllUpgradeHTTPDNSNodesWithClusterIdRequest) returns (FindAllUpgradeHTTPDNSNodesWithClusterIdResponse);",
+ "doc": "列出所有需要升级的HTTPDNS节点",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "upgradeHTTPDNSNode",
+ "requestMessageName": "UpgradeHTTPDNSNodeRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc upgradeHTTPDNSNode (UpgradeHTTPDNSNodeRequest) returns (RPCSuccess);",
+ "doc": "升级单个HTTPDNS节点",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_node.proto",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSRuleService",
+ "methods": [
+ {
+ "name": "createHTTPDNSCustomRule",
+ "requestMessageName": "CreateHTTPDNSCustomRuleRequest",
+ "responseMessageName": "CreateHTTPDNSCustomRuleResponse",
+ "code": "rpc createHTTPDNSCustomRule (CreateHTTPDNSCustomRuleRequest) returns (CreateHTTPDNSCustomRuleResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSCustomRule",
+ "requestMessageName": "UpdateHTTPDNSCustomRuleRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSCustomRule (UpdateHTTPDNSCustomRuleRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "deleteHTTPDNSCustomRule",
+ "requestMessageName": "DeleteHTTPDNSCustomRuleRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc deleteHTTPDNSCustomRule (DeleteHTTPDNSCustomRuleRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "updateHTTPDNSCustomRuleStatus",
+ "requestMessageName": "UpdateHTTPDNSCustomRuleStatusRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc updateHTTPDNSCustomRuleStatus (UpdateHTTPDNSCustomRuleStatusRequest) returns (RPCSuccess);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "listHTTPDNSCustomRulesWithDomainId",
+ "requestMessageName": "ListHTTPDNSCustomRulesWithDomainIdRequest",
+ "responseMessageName": "ListHTTPDNSCustomRulesWithDomainIdResponse",
+ "code": "rpc listHTTPDNSCustomRulesWithDomainId (ListHTTPDNSCustomRulesWithDomainIdRequest) returns (ListHTTPDNSCustomRulesWithDomainIdResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_rule.proto",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSRuntimeLogService",
+ "methods": [
+ {
+ "name": "createHTTPDNSRuntimeLogs",
+ "requestMessageName": "CreateHTTPDNSRuntimeLogsRequest",
+ "responseMessageName": "CreateHTTPDNSRuntimeLogsResponse",
+ "code": "rpc createHTTPDNSRuntimeLogs (CreateHTTPDNSRuntimeLogsRequest) returns (CreateHTTPDNSRuntimeLogsResponse);",
+ "doc": "",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "listHTTPDNSRuntimeLogs",
+ "requestMessageName": "ListHTTPDNSRuntimeLogsRequest",
+ "responseMessageName": "ListHTTPDNSRuntimeLogsResponse",
+ "code": "rpc listHTTPDNSRuntimeLogs (ListHTTPDNSRuntimeLogsRequest) returns (ListHTTPDNSRuntimeLogsResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_runtime_log.proto",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSSandboxService",
+ "methods": [
+ {
+ "name": "testHTTPDNSResolve",
+ "requestMessageName": "TestHTTPDNSResolveRequest",
+ "responseMessageName": "TestHTTPDNSResolveResponse",
+ "code": "rpc testHTTPDNSResolve (TestHTTPDNSResolveRequest) returns (TestHTTPDNSResolveResponse);",
+ "doc": "",
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "isDeprecated": false
+ }
+ ],
+ "filename": "service_httpdns_sandbox.proto",
+ "doc": ""
+ },
{
"name": "IPItemService",
"methods": [
@@ -8505,6 +9063,28 @@
],
"isDeprecated": false
},
+ {
+ "name": "findAllUpgradeNSNodesWithNSClusterId",
+ "requestMessageName": "FindAllUpgradeNSNodesWithNSClusterIdRequest",
+ "responseMessageName": "FindAllUpgradeNSNodesWithNSClusterIdResponse",
+ "code": "rpc findAllUpgradeNSNodesWithNSClusterId (FindAllUpgradeNSNodesWithNSClusterIdRequest) returns (FindAllUpgradeNSNodesWithNSClusterIdResponse);",
+ "doc": "列出所有需要升级的NS节点",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
+ {
+ "name": "upgradeNSNode",
+ "requestMessageName": "UpgradeNSNodeRequest",
+ "responseMessageName": "RPCSuccess",
+ "code": "rpc upgradeNSNode (UpgradeNSNodeRequest) returns (RPCSuccess);",
+ "doc": "升级单个NS节点",
+ "roles": [
+ "admin"
+ ],
+ "isDeprecated": false
+ },
{
"name": "createNSNode",
"requestMessageName": "CreateNSNodeRequest",
@@ -14382,6 +14962,16 @@
"code": "message CheckDBNodeStatusResponse {\n\tDBNodeStatus dbNodeStatus = 1;\n}",
"doc": ""
},
+ {
+ "name": "CheckHTTPDNSNodeLatestVersionRequest",
+ "code": "message CheckHTTPDNSNodeLatestVersionRequest {\r\n\tstring os = 1;\r\n\tstring arch = 2;\r\n\tstring currentVersion = 3;\r\n}",
+ "doc": "检查HTTPDNS节点新版本"
+ },
+ {
+ "name": "CheckHTTPDNSNodeLatestVersionResponse",
+ "code": "message CheckHTTPDNSNodeLatestVersionResponse {\r\n\tbool hasNewVersion = 1;\r\n\tstring newVersion = 2;\r\n}",
+ "doc": ""
+ },
{
"name": "CheckHTTPFirewallPolicyIPStatusRequest",
"code": "message CheckHTTPFirewallPolicyIPStatusRequest {\n\tint64 httpFirewallPolicyId = 1;\n\tstring ip = 2;\n}",
@@ -14404,12 +14994,12 @@
},
{
"name": "CheckNSNodeLatestVersionRequest",
- "code": "message CheckNSNodeLatestVersionRequest {\n\tstring os = 1;\n\tstring arch = 2;\n\tstring currentVersion = 3;\n}",
+ "code": "message CheckNSNodeLatestVersionRequest {\r\n\tstring os = 1;\r\n\tstring arch = 2;\r\n\tstring currentVersion = 3;\r\n}",
"doc": "检查NS节点新版本"
},
{
"name": "CheckNSNodeLatestVersionResponse",
- "code": "message CheckNSNodeLatestVersionResponse {\n\tbool hasNewVersion = 1;\n\tstring newVersion = 2;\n}",
+ "code": "message CheckNSNodeLatestVersionResponse {\r\n\tbool hasNewVersion = 1;\r\n\tstring newVersion = 2;\r\n}",
"doc": ""
},
{
@@ -14514,12 +15104,12 @@
},
{
"name": "CheckUserEmailRequest",
- "code": "message CheckUserEmailRequest {\n\tstring email = 1; // 邮箱地址\n}",
+ "code": "message CheckUserEmailRequest {\r\n\tstring email = 1; // 邮箱地址\r\n}",
"doc": "检查邮箱是否已被验证"
},
{
"name": "CheckUserEmailResponse",
- "code": "message CheckUserEmailResponse {\n\tbool exists = 1; // 是否已被使用\n}",
+ "code": "message CheckUserEmailResponse {\r\n\tbool exists = 1; // 是否已被使用\r\n}",
"doc": ""
},
{
@@ -14534,22 +15124,22 @@
},
{
"name": "CheckUserMobileRequest",
- "code": "message CheckUserMobileRequest {\n\tstring mobile = 1; // 手机号码\n}",
+ "code": "message CheckUserMobileRequest {\r\n\tstring mobile = 1; // 手机号码\r\n}",
"doc": "检查手机号码是否已被验证"
},
{
"name": "CheckUserMobileResponse",
- "code": "message CheckUserMobileResponse {\n\tbool exists = 1; // 是否已被使用\n}",
+ "code": "message CheckUserMobileResponse {\r\n\tbool exists = 1; // 是否已被使用\r\n}",
"doc": ""
},
{
"name": "CheckUserOTPWithUsernameRequest",
- "code": "message CheckUserOTPWithUsernameRequest {\n\tstring username = 1;\n}",
+ "code": "message CheckUserOTPWithUsernameRequest {\r\n\tstring username = 1;\r\n}",
"doc": "根据用户名检查是否需要输入OTP"
},
{
"name": "CheckUserOTPWithUsernameResponse",
- "code": "message CheckUserOTPWithUsernameResponse {\n\tbool requireOTP = 1;\n}",
+ "code": "message CheckUserOTPWithUsernameResponse {\r\n\tbool requireOTP = 1;\r\n}",
"doc": ""
},
{
@@ -14559,22 +15149,22 @@
},
{
"name": "CheckUserServersStateRequest",
- "code": "message CheckUserServersStateRequest {\n\tint64 userId = 1;\n}",
+ "code": "message CheckUserServersStateRequest {\r\n\tint64 userId = 1;\r\n}",
"doc": "检查用户服务可用状态"
},
{
"name": "CheckUserServersStateResponse",
- "code": "message CheckUserServersStateResponse {\n\tbool isEnabled = 1;\n}",
+ "code": "message CheckUserServersStateResponse {\r\n\tbool isEnabled = 1;\r\n}",
"doc": ""
},
{
"name": "CheckUserUsernameRequest",
- "code": "message CheckUserUsernameRequest {\n\tint64 userId = 1;\n\tstring username = 2;\n}",
+ "code": "message CheckUserUsernameRequest {\r\n\tint64 userId = 1;\r\n\tstring username = 2;\r\n}",
"doc": "检查用户名是否存在"
},
{
"name": "CheckUserUsernameResponse",
- "code": "message CheckUserUsernameResponse {\n\tbool exists = 1;\n}",
+ "code": "message CheckUserUsernameResponse {\r\n\tbool exists = 1;\r\n}",
"doc": ""
},
{
@@ -14642,6 +15232,11 @@
"code": "message ComposeFirewallGlobalBoardResponse {\n\tint64 countDailyLogs = 1;\n\tint64 countDailyBlocks = 2;\n\tint64 countDailyCaptcha = 3;\n\tint64 countWeeklyBlocks = 4;\n\n\trepeated HTTPFirewallRuleGroupStat httpFirewallRuleGroups = 30;\n\trepeated DailyStat dailyStats = 31;\n\trepeated HourlyStat hourlyStats = 32;\n\trepeated NodeStat topNodeStats = 33;\n\trepeated DomainStat topDomainStats = 34;\n\trepeated CountryStat topCountryStats = 35;\n\n\n\tmessage HTTPFirewallRuleGroupStat {\n\t\tHTTPFirewallRuleGroup httpFirewallRuleGroup = 1;\n\t\tint64 count = 2;\n\t}\n\n\n\tmessage HourlyStat {\n\t\tstring hour = 1;\n\t\tint64 countLogs = 2;\n\t\tint64 countCaptcha = 3;\n\t\tint64 countBlocks = 4;\n\t}\n\n\n\tmessage DailyStat {\n\t\tstring day = 1;\n\t\tint64 countLogs = 2;\n\t\tint64 countCaptcha = 3;\n\t\tint64 countBlocks = 4;\n\t}\n\n\n\tmessage NodeStat {\n\t\tint64 nodeId = 1;\n\t\tstring nodeName = 2;\n\t\tint64 countRequests = 3;\n\t\tint64 bytes = 4;\n\t\tint64 countAttackRequests = 6;\n\t\tint64 attackBytes = 7;\n\t}\n\n\n\tmessage DomainStat {\n\t\tint64 serverId = 1;\n\t\tstring domain = 2;\n\t\tint64 countRequests = 3;\n\t\tint64 bytes = 4;\n\t\tint64 countAttackRequests = 6;\n\t\tint64 attackBytes = 7;\n\t}\n\n\n\tmessage CountryStat {\n\t\tstring countryName = 1;\n\t\tint64 bytes = 2;\n\t\tint64 countRequests = 3;\n\t\tfloat percent = 4; // 流量占比\n\t\tint64 countAttackRequests = 6;\n\t\tint64 attackBytes = 7;\n\t}\n}",
"doc": ""
},
+ {
+ "name": "ComposeHTTPDNSBoardResponse",
+ "code": "message ComposeHTTPDNSBoardResponse {\n\tint64 countApps = 1;\n\tint64 countDomains = 2;\n\tint64 countClusters = 3;\n\tint64 countNodes = 4;\n\tint64 countOfflineNodes = 5;\n\n\n\tmessage DailyTrafficStat {\n\t\tstring day = 1;\n\t\tint64 bytes = 2;\n\t\tint64 countRequests = 3;\n\t}\n\n\n\tmessage HourlyTrafficStat {\n\t\tstring hour = 1;\n\t\tint64 bytes = 2;\n\t\tint64 countRequests = 3;\n\t}\n\n\n\tmessage TopAppStat {\n\t\tint64 appId = 1;\n\t\tstring appName = 2;\n\t\tint64 countRequests = 3;\n\t\tint64 bytes = 4;\n\t}\n\n\n\tmessage TopDomainStat {\n\t\tint64 domainId = 1;\n\t\tstring domainName = 2;\n\t\tint64 countRequests = 3;\n\t\tint64 bytes = 4;\n\t}\n\n\n\tmessage TopNodeStat {\n\t\tint64 clusterId = 1;\n\t\tint64 nodeId = 2;\n\t\tstring nodeName = 3;\n\t\tint64 countRequests = 4;\n\t\tint64 bytes = 5;\n\t}\n\n\trepeated DailyTrafficStat dailyTrafficStats = 30;\n\trepeated HourlyTrafficStat hourlyTrafficStats = 31;\n\trepeated TopAppStat topAppStats = 32;\n\trepeated TopDomainStat topDomainStats = 33;\n\trepeated TopNodeStat topNodeStats = 34;\n\trepeated NodeValue cpuNodeValues = 35;\n\trepeated NodeValue memoryNodeValues = 36;\n\trepeated NodeValue loadNodeValues = 37;\n}",
+ "doc": "组合看板数据响应"
+ },
{
"name": "ComposeNSBoardRequest",
"code": "message ComposeNSBoardRequest {\n\n}",
@@ -14724,22 +15319,22 @@
},
{
"name": "ComposeUserDashboardRequest",
- "code": "message ComposeUserDashboardRequest {\n\tint64 userId = 1;\n}",
+ "code": "message ComposeUserDashboardRequest {\r\n\tint64 userId = 1;\r\n}",
"doc": "取得用户Dashboard数据"
},
{
"name": "ComposeUserDashboardResponse",
- "code": "message ComposeUserDashboardResponse {\n\tint64 countServers = 1;\n\tint64 monthlyTrafficBytes = 2;\n\tint64 monthlyPeekBandwidthBytes = 3;\n\tint64 dailyTrafficBytes = 4;\n\tint64 dailyPeekBandwidthBytes = 5;\n\trepeated DailyTrafficStat dailyTrafficStats = 6;\n\trepeated DailyPeekBandwidthStat dailyPeekBandwidthStats = 7;\n\tint32 bandwidthPercentile = 8; // 带宽百分位\n\tint64 bandwidthPercentileBits = 9; // 带宽百分位上的比特数\n\n\n\tmessage DailyTrafficStat {\n\t\tstring day = 1;\n\t\tint64 bytes = 2;\n\t\tint64 cachedBytes = 3;\n\t\tint64 attackBytes = 4;\n\t\tint64 countRequests = 5;\n\t\tint64 countCachedRequests = 6;\n\t\tint64 countAttackRequests = 7;\n\t}\n\n\n\tmessage DailyPeekBandwidthStat {\n\t\tstring day = 1;\n\t\tint64 bytes = 2;\n\t}\n}",
+ "code": "message ComposeUserDashboardResponse {\r\n\tint64 countServers = 1;\r\n\tint64 monthlyTrafficBytes = 2;\r\n\tint64 monthlyPeekBandwidthBytes = 3;\r\n\tint64 dailyTrafficBytes = 4;\r\n\tint64 dailyPeekBandwidthBytes = 5;\r\n\trepeated DailyTrafficStat dailyTrafficStats = 6;\r\n\trepeated DailyPeekBandwidthStat dailyPeekBandwidthStats = 7;\r\n\tint32 bandwidthPercentile = 8; // 带宽百分位\r\n\tint64 bandwidthPercentileBits = 9; // 带宽百分位上的比特数\r\n\n\r\n\tmessage DailyTrafficStat {\r\n\t\tstring day = 1;\r\n\t\tint64 bytes = 2;\r\n\t\tint64 cachedBytes = 3;\r\n\t\tint64 attackBytes = 4;\r\n\t\tint64 countRequests = 5;\r\n\t\tint64 countCachedRequests = 6;\r\n\t\tint64 countAttackRequests = 7;\r\n\t}\r\n\n\r\n\tmessage DailyPeekBandwidthStat {\r\n\t\tstring day = 1;\r\n\t\tint64 bytes = 2;\r\n\t}\r\n}",
"doc": ""
},
{
"name": "ComposeUserGlobalBoardRequest",
- "code": "message ComposeUserGlobalBoardRequest {\n\n}",
+ "code": "message ComposeUserGlobalBoardRequest {\r\n\r\n}",
"doc": "组合看板数据"
},
{
"name": "ComposeUserGlobalBoardResponse",
- "code": "message ComposeUserGlobalBoardResponse {\n\tint64 totalUsers = 1;\n\tint64 countTodayUsers = 2;\n\tint64 countWeeklyUsers = 3;\n\tint64 countUserNodes = 4;\n\tint64 countOfflineUserNodes = 5;\n\tint64 countVerifyingUsers = 6;\n\n\trepeated DailyStat dailyStats = 30;\n\trepeated NodeValue cpuNodeValues = 31;\n\trepeated NodeValue memoryNodeValues = 32;\n\trepeated NodeValue loadNodeValues = 33;\n\trepeated TrafficStat topTrafficStats = 34;\n\n\n\tmessage DailyStat {\n\t\tstring day = 1;\n\t\tint64 count = 2;\n\t}\n\n\n\tmessage TrafficStat {\n\t\tint64 userId = 1;\n\t\tstring userName = 2;\n\t\tint64 countRequests = 3;\n\t\tint64 bytes = 4;\n\t}\n}",
+ "code": "message ComposeUserGlobalBoardResponse {\r\n\tint64 totalUsers = 1;\r\n\tint64 countTodayUsers = 2;\r\n\tint64 countWeeklyUsers = 3;\r\n\tint64 countUserNodes = 4;\r\n\tint64 countOfflineUserNodes = 5;\r\n\tint64 countVerifyingUsers = 6;\r\n\r\n\trepeated DailyStat dailyStats = 30;\r\n\trepeated NodeValue cpuNodeValues = 31;\r\n\trepeated NodeValue memoryNodeValues = 32;\r\n\trepeated NodeValue loadNodeValues = 33;\r\n\trepeated TrafficStat topTrafficStats = 34;\r\n\n\r\n\tmessage DailyStat {\r\n\t\tstring day = 1;\r\n\t\tint64 count = 2;\r\n\t}\r\n\n\r\n\tmessage TrafficStat {\r\n\t\tint64 userId = 1;\r\n\t\tstring userName = 2;\r\n\t\tint64 countRequests = 3;\r\n\t\tint64 bytes = 4;\r\n\t}\r\n}",
"doc": ""
},
{
@@ -15019,12 +15614,12 @@
},
{
"name": "CountAllEnabledUsersRequest",
- "code": "message CountAllEnabledUsersRequest {\n\tstring keyword = 1;\n\tbool isVerifying = 2;\n\tint32 mobileIsVerified = 3; // 手机号是否已验证,1表示已验证,0表示未验证,-1表示所有状态\n}",
+ "code": "message CountAllEnabledUsersRequest {\r\n\tstring keyword = 1;\r\n\tbool isVerifying = 2;\r\n\tint32 mobileIsVerified = 3; // 手机号是否已验证,1表示已验证,0表示未验证,-1表示所有状态\r\n}",
"doc": "计算用户数量"
},
{
"name": "CountAllHTTPAccessLogPoliciesRequest",
- "code": "message CountAllHTTPAccessLogPoliciesRequest {\n\n}",
+ "code": "message CountAllHTTPAccessLogPoliciesRequest {\r\n\r\n}",
"doc": "计算访问日志策略数量"
},
{
@@ -15049,12 +15644,12 @@
},
{
"name": "CountAllNSNodesMatchRequest",
- "code": "message CountAllNSNodesMatchRequest {\n\tint64 nsClusterId = 1;\n\tint32 installState = 2;\n\tint32 activeState = 3;\n\tstring keyword = 4;\n\t//int64 nodeGroupId = 5;\n\t//int64 nodeRegionId = 6;\n}",
+ "code": "message CountAllNSNodesMatchRequest {\r\n\tint64 nsClusterId = 1;\r\n\tint32 installState = 2;\r\n\tint32 activeState = 3;\r\n\tstring keyword = 4;\r\n\t//int64 nodeGroupId = 5;\r\n\t//int64 nodeRegionId = 6;\r\n}",
"doc": "计算匹配的NS节点数量"
},
{
"name": "CountAllNSNodesRequest",
- "code": "message CountAllNSNodesRequest {\n\n}",
+ "code": "message CountAllNSNodesRequest {\r\n\r\n}",
"doc": "所有可用的NS节点数量"
},
{
@@ -15112,9 +15707,14 @@
"code": "message CountAllServerNamesWithUserIdRequest {\n\tint64 userId = 1; // 用户ID\n\tint64 userPlanId = 2; // 用户套餐ID\n}",
"doc": "计算一个用户下的所有域名数量"
},
+ {
+ "name": "CountAllUpgradeHTTPDNSNodesWithClusterIdRequest",
+ "code": "message CountAllUpgradeHTTPDNSNodesWithClusterIdRequest {\r\n\tint64 clusterId = 1;\r\n}",
+ "doc": "计算需要升级的HTTPDNS节点数量"
+ },
{
"name": "CountAllUpgradeNSNodesWithNSClusterIdRequest",
- "code": "message CountAllUpgradeNSNodesWithNSClusterIdRequest {\n\tint64 nsClusterId = 1;\n}",
+ "code": "message CountAllUpgradeNSNodesWithNSClusterIdRequest {\r\n\tint64 nsClusterId = 1;\r\n}",
"doc": "计算需要升级的NS节点数量"
},
{
@@ -15479,12 +16079,12 @@
},
{
"name": "CreateHTTPAccessLogPolicyRequest",
- "code": "message CreateHTTPAccessLogPolicyRequest {\n\tstring name = 1;\n\tstring type = 2;\n\tbytes optionsJSON = 3;\n\tbytes condsJSON = 4;\n\tbool isPublic = 5;\n\tbool firewallOnly = 6;\n\tbool disableDefaultDB = 7;\n}",
+ "code": "message CreateHTTPAccessLogPolicyRequest {\r\n\tstring name = 1;\r\n\tstring type = 2;\r\n\tbytes optionsJSON = 3;\r\n\tbytes condsJSON = 4;\r\n\tbool isPublic = 5;\r\n\tbool firewallOnly = 6;\r\n\tbool disableDefaultDB = 7;\r\n\tbytes writeTargetsJSON = 8;\r\n}",
"doc": "创建访问日志策略"
},
{
"name": "CreateHTTPAccessLogPolicyResponse",
- "code": "message CreateHTTPAccessLogPolicyResponse {\n\tint64 httpAccessLogPolicyId = 1;\n}",
+ "code": "message CreateHTTPAccessLogPolicyResponse {\r\n\tint64 httpAccessLogPolicyId = 1;\r\n}",
"doc": ""
},
{
@@ -15527,6 +16127,76 @@
"code": "message CreateHTTPCacheTaskResponse {\n\tint64 httpCacheTaskId = 1; // 生成的任务ID\n\tint64 countKeys = 2; // 任务中包含的Key\n}",
"doc": ""
},
+ {
+ "name": "CreateHTTPDNSAccessLogsRequest",
+ "code": "message CreateHTTPDNSAccessLogsRequest {\r\n\trepeated HTTPDNSAccessLog logs = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSAccessLogsResponse",
+ "code": "message CreateHTTPDNSAccessLogsResponse {\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSAppRequest",
+ "code": "message CreateHTTPDNSAppRequest {\r\n\tstring name = 1;\r\n\tstring appId = 2;\r\n\treserved 3, 4; // removed: primaryClusterId, backupClusterId\r\n\tbool isOn = 5;\r\n\tbool signEnabled = 6;\r\n\tint64 userId = 7;\r\n\tbytes clusterIdsJSON = 8;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSAppResponse",
+ "code": "message CreateHTTPDNSAppResponse {\r\n\tint64 appDbId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSClusterRequest",
+ "code": "message CreateHTTPDNSClusterRequest {\r\n\tstring name = 1;\r\n\tstring serviceDomain = 2;\r\n\tint32 defaultTTL = 3;\r\n\tint32 fallbackTimeoutMs = 4;\r\n\tstring installDir = 5;\r\n\tbytes tlsPolicyJSON = 6;\r\n\tbool isOn = 7;\r\n\tbool isDefault = 8;\r\n\tbool autoRemoteStart = 9;\r\n\tbool accessLogIsOn = 10;\r\n\tstring timeZone = 11;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSClusterResponse",
+ "code": "message CreateHTTPDNSClusterResponse {\r\n\tint64 clusterId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSCustomRuleRequest",
+ "code": "message CreateHTTPDNSCustomRuleRequest {\r\n\tHTTPDNSCustomRule rule = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSCustomRuleResponse",
+ "code": "message CreateHTTPDNSCustomRuleResponse {\r\n\tint64 ruleId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSDomainRequest",
+ "code": "message CreateHTTPDNSDomainRequest {\r\n\tint64 appDbId = 1;\r\n\tstring domain = 2;\r\n\tbool isOn = 3;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSDomainResponse",
+ "code": "message CreateHTTPDNSDomainResponse {\r\n\tint64 domainId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSNodeRequest",
+ "code": "message CreateHTTPDNSNodeRequest {\r\n\tint64 clusterId = 1;\r\n\tstring name = 2;\r\n\tstring installDir = 3;\r\n\tbool isOn = 4;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSNodeResponse",
+ "code": "message CreateHTTPDNSNodeResponse {\r\n\tint64 nodeId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSRuntimeLogsRequest",
+ "code": "message CreateHTTPDNSRuntimeLogsRequest {\r\n\trepeated HTTPDNSRuntimeLog logs = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "CreateHTTPDNSRuntimeLogsResponse",
+ "code": "message CreateHTTPDNSRuntimeLogsResponse {\r\n}",
+ "doc": ""
+ },
{
"name": "CreateHTTPFastcgiRequest",
"code": "message CreateHTTPFastcgiRequest {\n\tbool isOn = 1;\n\tstring address = 2;\n\tbytes paramsJSON = 3;\n\tbytes readTimeoutJSON = 4;\n\tbytes connTimeoutJSON = 5;\n\tint32 poolSize = 6;\n\tstring pathInfoPattern = 7;\n}",
@@ -15839,12 +16509,12 @@
},
{
"name": "CreateNSNodeRequest",
- "code": "message CreateNSNodeRequest {\n\tstring name = 1;\n\tint64 nodeClusterId = 2;\n\tNodeLogin nodeLogin = 3;\n}",
+ "code": "message CreateNSNodeRequest {\r\n\tstring name = 1;\r\n\tint64 nodeClusterId = 2;\r\n\tNodeLogin nodeLogin = 3;\r\n}",
"doc": "创建NS节点"
},
{
"name": "CreateNSNodeResponse",
- "code": "message CreateNSNodeResponse {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message CreateNSNodeResponse {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": ""
},
{
@@ -16284,12 +16954,12 @@
},
{
"name": "CreateUserRequest",
- "code": "message CreateUserRequest {\n\tstring username = 1;\n\tstring password = 2;\n\tstring fullname = 3;\n\tstring mobile = 4;\n\tstring tel = 5;\n\tstring email = 6;\n\tstring remark = 7;\n\tstring source = 8;\n\tint64 nodeClusterId = 9;\n}",
+ "code": "message CreateUserRequest {\r\n\tstring username = 1;\r\n\tstring password = 2;\r\n\tstring fullname = 3;\r\n\tstring mobile = 4;\r\n\tstring tel = 5;\r\n\tstring email = 6;\r\n\tstring remark = 7;\r\n\tstring source = 8;\r\n\tint64 nodeClusterId = 9;\r\n}",
"doc": "创建用户"
},
{
"name": "CreateUserResponse",
- "code": "message CreateUserResponse {\n\tint64 userId = 1;\n}",
+ "code": "message CreateUserResponse {\r\n\tint64 userId = 1;\r\n}",
"doc": ""
},
{
@@ -16474,7 +17144,7 @@
},
{
"name": "DeleteHTTPAccessLogPolicyRequest",
- "code": "message DeleteHTTPAccessLogPolicyRequest {\n\tint64 httpAccessLogPolicyId = 1;\n}",
+ "code": "message DeleteHTTPAccessLogPolicyRequest {\r\n\tint64 httpAccessLogPolicyId = 1;\r\n}",
"doc": "删除策略"
},
{
@@ -16487,6 +17157,31 @@
"code": "message DeleteHTTPCacheTaskRequest {\n\tint64 httpCacheTaskId = 1; // 任务ID\n}",
"doc": "删除任务"
},
+ {
+ "name": "DeleteHTTPDNSAppRequest",
+ "code": "message DeleteHTTPDNSAppRequest {\r\n\tint64 appDbId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "DeleteHTTPDNSClusterRequest",
+ "code": "message DeleteHTTPDNSClusterRequest {\r\n\tint64 clusterId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "DeleteHTTPDNSCustomRuleRequest",
+ "code": "message DeleteHTTPDNSCustomRuleRequest {\r\n\tint64 ruleId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "DeleteHTTPDNSDomainRequest",
+ "code": "message DeleteHTTPDNSDomainRequest {\r\n\tint64 domainId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "DeleteHTTPDNSNodeRequest",
+ "code": "message DeleteHTTPDNSNodeRequest {\r\n\tint64 nodeId = 1;\r\n}",
+ "doc": ""
+ },
{
"name": "DeleteHTTPFirewallPolicyRequest",
"code": "message DeleteHTTPFirewallPolicyRequest {\n\tint64 httpFirewallPolicyId = 1;\n}",
@@ -16609,7 +17304,7 @@
},
{
"name": "DeleteNSNodeRequest",
- "code": "message DeleteNSNodeRequest {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message DeleteNSNodeRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": "删除NS节点"
},
{
@@ -16804,7 +17499,7 @@
},
{
"name": "DeleteUserRequest",
- "code": "message DeleteUserRequest {\n\tint64 userId = 1;\n}",
+ "code": "message DeleteUserRequest {\r\n\tint64 userId = 1;\r\n}",
"doc": "删除用户"
},
{
@@ -16877,14 +17572,24 @@
"code": "message DownloadFileChunkResponse {\n\tFileChunk fileChunk = 1;\n}",
"doc": ""
},
+ {
+ "name": "DownloadHTTPDNSNodeInstallationFileRequest",
+ "code": "message DownloadHTTPDNSNodeInstallationFileRequest {\r\n\tstring os = 1;\r\n\tstring arch = 2;\r\n\tint64 chunkOffset = 3;\r\n}",
+ "doc": "下载最新HTTPDNS节点安装文件"
+ },
+ {
+ "name": "DownloadHTTPDNSNodeInstallationFileResponse",
+ "code": "message DownloadHTTPDNSNodeInstallationFileResponse {\r\n\tbytes chunkData = 1;\r\n\tstring sum = 2;\r\n\tint64 offset = 3;\r\n\tstring version = 4;\r\n\tstring filename = 5;\r\n}",
+ "doc": ""
+ },
{
"name": "DownloadNSNodeInstallationFileRequest",
- "code": "message DownloadNSNodeInstallationFileRequest {\n\tstring os = 1;\n\tstring arch = 2;\n\tint64 chunkOffset = 3;\n}",
+ "code": "message DownloadNSNodeInstallationFileRequest {\r\n\tstring os = 1;\r\n\tstring arch = 2;\r\n\tint64 chunkOffset = 3;\r\n}",
"doc": "下载最新NS节点安装文件"
},
{
"name": "DownloadNSNodeInstallationFileResponse",
- "code": "message DownloadNSNodeInstallationFileResponse {\n\tbytes chunkData = 1;\n\tstring sum = 2; // 文件的md5sum\n\tint64 offset = 3;\n\tstring version = 4;\n\tstring filename = 5;\n}",
+ "code": "message DownloadNSNodeInstallationFileResponse {\r\n\tbytes chunkData = 1;\r\n\tstring sum = 2; // 文件的md5sum\r\n\tint64 offset = 3;\r\n\tstring version = 4;\r\n\tstring filename = 5;\r\n}",
"doc": ""
},
{
@@ -17907,6 +18612,26 @@
"code": "message FindAllFinishedIPLibraryFilesResponse {\n\trepeated IPLibraryFile ipLibraryFiles = 1;\n}",
"doc": ""
},
+ {
+ "name": "FindAllHTTPDNSAppsRequest",
+ "code": "message FindAllHTTPDNSAppsRequest {\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindAllHTTPDNSAppsResponse",
+ "code": "message FindAllHTTPDNSAppsResponse {\r\n\trepeated HTTPDNSApp apps = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindAllHTTPDNSClustersRequest",
+ "code": "message FindAllHTTPDNSClustersRequest {\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindAllHTTPDNSClustersResponse",
+ "code": "message FindAllHTTPDNSClustersResponse {\r\n\trepeated HTTPDNSCluster clusters = 1;\r\n}",
+ "doc": ""
+ },
{
"name": "FindAllIPLibraryArtifactsRequest",
"code": "message FindAllIPLibraryArtifactsRequest {\n\n}",
@@ -17959,12 +18684,12 @@
},
{
"name": "FindAllNSNodesWithNSClusterIdRequest",
- "code": "message FindAllNSNodesWithNSClusterIdRequest {\n\tint64 nsClusterId = 1;\n}",
+ "code": "message FindAllNSNodesWithNSClusterIdRequest {\r\n\tint64 nsClusterId = 1;\r\n}",
"doc": "根据集群查找所有NS节点"
},
{
"name": "FindAllNSNodesWithNSClusterIdResponse",
- "code": "message FindAllNSNodesWithNSClusterIdResponse {\n\trepeated NSNode nsNodes = 1;\n}",
+ "code": "message FindAllNSNodesWithNSClusterIdResponse {\r\n\trepeated NSNode nsNodes = 1;\r\n}",
"doc": ""
},
{
@@ -18197,6 +18922,26 @@
"code": "message FindAllUnfinishedIPLibraryFilesResponse {\n\trepeated IPLibraryFile ipLibraryFiles = 1;\n}",
"doc": ""
},
+ {
+ "name": "FindAllUpgradeHTTPDNSNodesWithClusterIdRequest",
+ "code": "message FindAllUpgradeHTTPDNSNodesWithClusterIdRequest {\r\n\tint64 clusterId = 1;\r\n}",
+ "doc": "列出所有需要升级的HTTPDNS节点"
+ },
+ {
+ "name": "FindAllUpgradeHTTPDNSNodesWithClusterIdResponse",
+ "code": "message FindAllUpgradeHTTPDNSNodesWithClusterIdResponse {\r\n\trepeated HTTPDNSNodeUpgrade nodes = 1;\r\n\n\r\n\tmessage HTTPDNSNodeUpgrade {\r\n\t\tHTTPDNSNode node = 1;\r\n\t\tstring os = 2;\r\n\t\tstring arch = 3;\r\n\t\tstring oldVersion = 4;\r\n\t\tstring newVersion = 5;\r\n\t}\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindAllUpgradeNSNodesWithNSClusterIdRequest",
+ "code": "message FindAllUpgradeNSNodesWithNSClusterIdRequest {\r\n\tint64 nsClusterId = 1;\r\n}",
+ "doc": "列出所有需要升级的NS节点"
+ },
+ {
+ "name": "FindAllUpgradeNSNodesWithNSClusterIdResponse",
+ "code": "message FindAllUpgradeNSNodesWithNSClusterIdResponse {\r\n\trepeated NSNodeUpgrade nodes = 1;\r\n\n\r\n\tmessage NSNodeUpgrade {\r\n\t\tNSNode nsNode = 1;\r\n\t\tstring os = 2;\r\n\t\tstring arch = 3;\r\n\t\tstring oldVersion = 4;\r\n\t\tstring newVersion = 5;\r\n\t}\r\n}",
+ "doc": ""
+ },
{
"name": "FindAllUpgradeNodesWithNodeClusterIdRequest",
"code": "message FindAllUpgradeNodesWithNodeClusterIdRequest {\n\tint64 nodeClusterId = 1;\n}",
@@ -18209,12 +18954,12 @@
},
{
"name": "FindAllUserFeatureDefinitionsRequest",
- "code": "message FindAllUserFeatureDefinitionsRequest {\n\n}",
+ "code": "message FindAllUserFeatureDefinitionsRequest {\r\n\r\n}",
"doc": "获取所有的功能定义"
},
{
"name": "FindAllUserFeatureDefinitionsResponse",
- "code": "message FindAllUserFeatureDefinitionsResponse {\n\trepeated UserFeature features = 1;\n}",
+ "code": "message FindAllUserFeatureDefinitionsResponse {\r\n\trepeated UserFeature features = 1;\r\n}",
"doc": ""
},
{
@@ -18364,12 +19109,12 @@
},
{
"name": "FindCurrentNSNodeConfigRequest",
- "code": "message FindCurrentNSNodeConfigRequest {\n\n}",
+ "code": "message FindCurrentNSNodeConfigRequest {\r\n\r\n}",
"doc": "获取当前NS节点信息"
},
{
"name": "FindCurrentNSNodeConfigResponse",
- "code": "message FindCurrentNSNodeConfigResponse {\n\tbytes nsNodeJSON = 1;\n}",
+ "code": "message FindCurrentNSNodeConfigResponse {\r\n\tbytes nsNodeJSON = 1;\r\n}",
"doc": ""
},
{
@@ -19324,12 +20069,12 @@
},
{
"name": "FindEnabledUserRequest",
- "code": "message FindEnabledUserRequest {\n\tint64 userId = 1;\n}",
+ "code": "message FindEnabledUserRequest {\r\n\tint64 userId = 1;\r\n}",
"doc": "查询单个用户信息"
},
{
"name": "FindEnabledUserResponse",
- "code": "message FindEnabledUserResponse {\n\tUser user = 1;\n}",
+ "code": "message FindEnabledUserResponse {\r\n\tUser user = 1;\r\n}",
"doc": ""
},
{
@@ -19384,12 +20129,12 @@
},
{
"name": "FindHTTPAccessLogPolicyRequest",
- "code": "message FindHTTPAccessLogPolicyRequest {\n\tint64 httpAccessLogPolicyId = 1;\n}",
+ "code": "message FindHTTPAccessLogPolicyRequest {\r\n\tint64 httpAccessLogPolicyId = 1;\r\n}",
"doc": "查找单个访问日志策略"
},
{
"name": "FindHTTPAccessLogPolicyResponse",
- "code": "message FindHTTPAccessLogPolicyResponse {\n\tHTTPAccessLogPolicy httpAccessLogPolicy = 1;\n}",
+ "code": "message FindHTTPAccessLogPolicyResponse {\r\n\tHTTPAccessLogPolicy httpAccessLogPolicy = 1;\r\n}",
"doc": ""
},
{
@@ -19402,6 +20147,36 @@
"code": "message FindHTTPAccessLogResponse {\n\tHTTPAccessLog httpAccessLog = 1;\n}",
"doc": ""
},
+ {
+ "name": "FindHTTPDNSAppRequest",
+ "code": "message FindHTTPDNSAppRequest {\r\n\tint64 appDbId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindHTTPDNSAppResponse",
+ "code": "message FindHTTPDNSAppResponse {\r\n\tHTTPDNSApp app = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindHTTPDNSClusterRequest",
+ "code": "message FindHTTPDNSClusterRequest {\r\n\tint64 clusterId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindHTTPDNSClusterResponse",
+ "code": "message FindHTTPDNSClusterResponse {\r\n\tHTTPDNSCluster cluster = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindHTTPDNSNodeRequest",
+ "code": "message FindHTTPDNSNodeRequest {\r\n\tint64 nodeId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "FindHTTPDNSNodeResponse",
+ "code": "message FindHTTPDNSNodeResponse {\r\n\tHTTPDNSNode node = 1;\r\n}",
+ "doc": ""
+ },
{
"name": "FindHTTPWebCCRequest",
"code": "message FindHTTPWebCCRequest {\n\tint64 httpWebId = 1;\n}",
@@ -19544,12 +20319,12 @@
},
{
"name": "FindLatestNSNodeVersionRequest",
- "code": "message FindLatestNSNodeVersionRequest {\n\n}",
+ "code": "message FindLatestNSNodeVersionRequest {\r\n\r\n}",
"doc": "取得最新的版本号"
},
{
"name": "FindLatestNSNodeVersionResponse",
- "code": "message FindLatestNSNodeVersionResponse {\n\tstring version = 1;\n}",
+ "code": "message FindLatestNSNodeVersionResponse {\r\n\tstring version = 1;\r\n}",
"doc": ""
},
{
@@ -19864,42 +20639,42 @@
},
{
"name": "FindNSNodeAPIConfigRequest",
- "code": "message FindNSNodeAPIConfigRequest {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message FindNSNodeAPIConfigRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": "查找单个节点的API相关配置"
},
{
"name": "FindNSNodeAPIConfigResponse",
- "code": "message FindNSNodeAPIConfigResponse {\n\tbytes apiNodeAddrsJSON = 1;\n}",
+ "code": "message FindNSNodeAPIConfigResponse {\r\n\tbytes apiNodeAddrsJSON = 1;\r\n}",
"doc": ""
},
{
"name": "FindNSNodeDDoSProtectionRequest",
- "code": "message FindNSNodeDDoSProtectionRequest {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message FindNSNodeDDoSProtectionRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": "获取NS节点的DDoS设置"
},
{
"name": "FindNSNodeDDoSProtectionResponse",
- "code": "message FindNSNodeDDoSProtectionResponse {\n\tbytes ddosProtectionJSON = 1;\n}",
+ "code": "message FindNSNodeDDoSProtectionResponse {\r\n\tbytes ddosProtectionJSON = 1;\r\n}",
"doc": ""
},
{
"name": "FindNSNodeInstallStatusRequest",
- "code": "message FindNSNodeInstallStatusRequest {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message FindNSNodeInstallStatusRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": "读取NS节点安装状态"
},
{
"name": "FindNSNodeInstallStatusResponse",
- "code": "message FindNSNodeInstallStatusResponse {\n\tNodeInstallStatus installStatus = 1;\n}",
+ "code": "message FindNSNodeInstallStatusResponse {\r\n\tNodeInstallStatus installStatus = 1;\r\n}",
"doc": ""
},
{
"name": "FindNSNodeRequest",
- "code": "message FindNSNodeRequest {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message FindNSNodeRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": "获取单个NS节点信息"
},
{
"name": "FindNSNodeResponse",
- "code": "message FindNSNodeResponse {\n\tNSNode nsNode = 1;\n}",
+ "code": "message FindNSNodeResponse {\r\n\tNSNode nsNode = 1;\r\n}",
"doc": ""
},
{
@@ -20609,12 +21384,12 @@
},
{
"name": "FindUserFeaturesRequest",
- "code": "message FindUserFeaturesRequest {\n\tint64 userId = 1;\n}",
+ "code": "message FindUserFeaturesRequest {\r\n\tint64 userId = 1;\r\n}",
"doc": "获取用户所有的功能列表"
},
{
"name": "FindUserFeaturesResponse",
- "code": "message FindUserFeaturesResponse {\n\trepeated UserFeature features = 1;\n}",
+ "code": "message FindUserFeaturesResponse {\r\n\trepeated UserFeature features = 1;\r\n}",
"doc": ""
},
{
@@ -20629,22 +21404,22 @@
},
{
"name": "FindUserNodeClusterIdRequest",
- "code": "message FindUserNodeClusterIdRequest {\n\tint64 userId = 1;\n}",
+ "code": "message FindUserNodeClusterIdRequest {\r\n\tint64 userId = 1;\r\n}",
"doc": "获取用户所在的集群ID"
},
{
"name": "FindUserNodeClusterIdResponse",
- "code": "message FindUserNodeClusterIdResponse {\n\tint64 nodeClusterId = 1;\n}",
+ "code": "message FindUserNodeClusterIdResponse {\r\n\tint64 nodeClusterId = 1;\r\n}",
"doc": ""
},
{
"name": "FindUserPriceInfoRequest",
- "code": "message FindUserPriceInfoRequest {\n\tint64 userId = 1;\n}",
+ "code": "message FindUserPriceInfoRequest {\r\n\tint64 userId = 1;\r\n}",
"doc": "读取用户计费信息"
},
{
"name": "FindUserPriceInfoResponse",
- "code": "message FindUserPriceInfoResponse {\n\tstring priceType = 1;\n\tstring pricePeriod = 2;\n}",
+ "code": "message FindUserPriceInfoResponse {\r\n\tstring priceType = 1;\r\n\tstring pricePeriod = 2;\r\n}",
"doc": ""
},
{
@@ -20699,12 +21474,12 @@
},
{
"name": "FindUserVerifiedEmailWithUsernameRequest",
- "code": "message FindUserVerifiedEmailWithUsernameRequest {\n\tstring username = 1; // 用户名\n}",
+ "code": "message FindUserVerifiedEmailWithUsernameRequest {\r\n\tstring username = 1; // 用户名\r\n}",
"doc": "根据用户名查询用户绑定的邮箱"
},
{
"name": "FindUserVerifiedEmailWithUsernameResponse",
- "code": "message FindUserVerifiedEmailWithUsernameResponse {\n\tstring email = 1; // 已绑定邮箱地址\n}",
+ "code": "message FindUserVerifiedEmailWithUsernameResponse {\r\n\tstring email = 1; // 已绑定邮箱地址\r\n}",
"doc": ""
},
{
@@ -20767,11 +21542,6 @@
"code": "message HTTPAccessLog {\n\tstring requestId = 48;\n\n\tint64 serverId = 1;\n\tint64 nodeId = 2;\n\tint64 locationId = 3;\n\tint64 rewriteId = 4;\n\tint64 originId = 5;\n\n\tstring remoteAddr = 6;\n\tstring rawRemoteAddr = 7;\n\tint32 remotePort = 8;\n\tstring remoteUser = 9;\n\tstring requestURI = 10;\n\tstring requestPath = 11;\n\tint64 requestLength = 12;\n\tdouble requestTime = 13;\n\tstring requestMethod = 14;\n\tstring requestFilename = 15;\n\tbytes requestBody = 51;\n\tstring scheme = 16;\n\tstring proto = 17;\n\tint64 bytesSent = 18;\n\tint64 bodyBytesSent = 19;\n\tint32 status = 20;\n\tstring statusMessage = 21;\n\tmap\u003cstring, Strings\u003e sentHeader = 22;\n\n\tstring timeISO8601 = 23;\n\tstring timeLocal = 24;\n\tdouble msec = 25;\n\tint64 timestamp = 26;\n\tstring host = 27;\n\tstring referer = 28;\n\tstring userAgent = 29;\n\tstring request = 30;\n\tstring contentType = 31;\n\tmap\u003cstring, string\u003e cookie = 32;\n\tstring args = 34;\n\tstring queryString = 35;\n\tmap\u003cstring, Strings\u003e header = 36;\n\tstring serverName = 37;\n\tint32 serverPort = 38;\n\tstring serverProtocol = 39;\n\tstring hostname = 40;\n\n\t// 源站相关\n\tstring originAddress = 41;\n\tint32 originStatus = 52;\n\n\t// 错误信息\n\trepeated string errors = 42;\n\n\t// 扩展\n\tmap\u003cstring, string\u003e attrs = 43;\n\n\t// WAF相关\n\tint64 firewallPolicyId = 44;\n\tint64 firewallRuleGroupId = 45;\n\tint64 firewallRuleSetId = 46;\n\tint64 firewallRuleId = 47;\n\n\trepeated string firewallActions = 49;\n\trepeated string tags = 50;\n\n\t// 详情\n\tNode node = 100;\n\n}",
"doc": "HTTP访问日志"
},
- {
- "name": "HTTPAccessLogPolicy",
- "code": "message HTTPAccessLogPolicy {\n\tint64 id = 1; // 策略ID\n\tstring name = 2; // 策略名称\n\tbool isOn = 3; // 是否启用\n\tstring type = 4; // 策略类型\n\tbytes optionsJSON = 5; // 策略选项\n\tbytes condsJSON = 6; // 记录条件选项\n\tbool isPublic = 7; // 是否公用\n\tbool firewallOnly = 8; // 是否只记录WAF相关访问日志\n\tbool disableDefaultDB = 9; // 停用默认数据库存储\n}",
- "doc": ""
- },
{
"name": "HTTPAuthPolicy",
"code": "message HTTPAuthPolicy {\n\tint64 id = 1;\n\tbool isOn = 2;\n\tstring name = 3;\n\tstring type = 4;\n\tbytes paramsJSON = 5;\n}",
@@ -20792,6 +21562,51 @@
"code": "message HTTPCacheTaskKey {\n\tint64 id = 1; // 缓存键ID\n\tint64 taskId = 2; // 任务ID\n\tstring key = 3; // 缓存键\n\tstring type = 4; // 操作类型:purge|fetch\n\tstring keyType = 5; // 键类型:key|prefix\n\tbool isDone = 6; // 是否已完成\n\tbool isDoing = 9; // 是否执行中\n\tbytes errorsJSON = 7; // 错误信息\n\tint64 nodeClusterId = 8; // 所属集群ID\n\n\tNodeCluster nodeCluster = 30; // 所属集群,不一定有内容\n}",
"doc": ""
},
+ {
+ "name": "HTTPDNSAccessLog",
+ "code": "message HTTPDNSAccessLog {\r\n\tint64 id = 1;\r\n\tstring requestId = 2;\r\n\tint64 clusterId = 3;\r\n\tint64 nodeId = 4;\r\n\tstring appId = 5;\r\n\tstring appName = 6;\r\n\tstring domain = 7;\r\n\tstring qtype = 8;\r\n\tstring clientIP = 9;\r\n\tstring clientRegion = 10;\r\n\tstring carrier = 11;\r\n\tstring sdkVersion = 12;\r\n\tstring os = 13;\r\n\tstring resultIPs = 14;\r\n\tstring status = 15;\r\n\tstring errorCode = 16;\r\n\tint32 costMs = 17;\r\n\tint64 createdAt = 18;\r\n\tstring day = 19;\r\n\tstring summary = 20;\r\n\tstring nodeName = 21;\r\n\tstring clusterName = 22;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSApp",
+ "code": "message HTTPDNSApp {\r\n\tint64 id = 1;\r\n\tstring name = 2;\r\n\tstring appId = 3;\r\n\tbool isOn = 4;\r\n\treserved 5, 6; // removed: primaryClusterId, backupClusterId\r\n\tstring sniMode = 7;\r\n\tbool signEnabled = 8;\r\n\tstring signSecret = 9;\r\n\tint64 signUpdatedAt = 10;\r\n\tint64 createdAt = 11;\r\n\tint64 updatedAt = 12;\r\n\tint64 userId = 13;\r\n\tbytes clusterIdsJSON = 14;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSCluster",
+ "code": "message HTTPDNSCluster {\r\n\tint64 id = 1;\r\n\tbool isOn = 2;\r\n\tbool isDefault = 3;\r\n\tstring name = 4;\r\n\tstring serviceDomain = 5;\r\n\tint32 defaultTTL = 6;\r\n\tint32 fallbackTimeoutMs = 7;\r\n\tstring installDir = 8;\r\n\tbytes tlsPolicyJSON = 9;\r\n\tint64 createdAt = 10;\r\n\tint64 updatedAt = 11;\r\n\tbool autoRemoteStart = 12;\r\n\tbool accessLogIsOn = 13;\r\n\tstring timeZone = 14;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSCustomRule",
+ "code": "message HTTPDNSCustomRule {\r\n\tint64 id = 1;\r\n\tint64 appId = 2;\r\n\tint64 domainId = 3;\r\n\tstring ruleName = 4;\r\n\tstring lineScope = 5;\r\n\tstring lineCarrier = 6;\r\n\tstring lineRegion = 7;\r\n\tstring lineProvince = 8;\r\n\tstring lineContinent = 9;\r\n\tstring lineCountry = 10;\r\n\tint32 ttl = 11;\r\n\tbool isOn = 12;\r\n\tint32 priority = 13;\r\n\tint64 updatedAt = 14;\r\n\trepeated HTTPDNSRuleRecord records = 15;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSDomain",
+ "code": "message HTTPDNSDomain {\r\n\tint64 id = 1;\r\n\tint64 appId = 2;\r\n\tstring domain = 3;\r\n\tbool isOn = 4;\r\n\tint64 createdAt = 5;\r\n\tint64 updatedAt = 6;\r\n\tint64 ruleCount = 7;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSNode",
+ "code": "message HTTPDNSNode {\r\n\tint64 id = 1;\r\n\tint64 clusterId = 2;\r\n\tstring name = 3;\r\n\tbool isOn = 4;\r\n\tbool isUp = 5;\r\n\tbool isInstalled = 6;\r\n\tbool isActive = 7;\r\n\tstring uniqueId = 8;\r\n\tstring secret = 9;\r\n\tstring installDir = 10;\r\n\tbytes statusJSON = 11;\r\n\tbytes installStatusJSON = 12;\r\n\tint64 createdAt = 13;\r\n\tint64 updatedAt = 14;\r\n\tNodeLogin nodeLogin = 15;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSResolveRecord",
+ "code": "message HTTPDNSResolveRecord {\r\n\tstring type = 1;\r\n\tstring ip = 2;\r\n\tint32 ttl = 3;\r\n\tint32 weight = 4;\r\n\tstring line = 5;\r\n\tstring region = 6;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSRuleRecord",
+ "code": "message HTTPDNSRuleRecord {\r\n\tint64 id = 1;\r\n\tint64 ruleId = 2;\r\n\tstring recordType = 3;\r\n\tstring recordValue = 4;\r\n\tint32 weight = 5;\r\n\tint32 sort = 6;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "HTTPDNSRuntimeLog",
+ "code": "message HTTPDNSRuntimeLog {\r\n\tint64 id = 1;\r\n\tint64 clusterId = 2;\r\n\tint64 nodeId = 3;\r\n\tstring level = 4;\r\n\tstring type = 5;\r\n\tstring module = 6;\r\n\tstring description = 7;\r\n\tint64 count = 8;\r\n\tstring requestId = 9;\r\n\tint64 createdAt = 10;\r\n\tstring day = 11;\r\n\tstring clusterName = 12;\r\n\tstring nodeName = 13;\r\n}",
+ "doc": ""
+ },
{
"name": "HTTPFastcgi",
"code": "message HTTPFastcgi {\n\tint64 id = 1;\n\tbool isOn = 2;\n\tstring address = 3;\n\tbytes paramsJSON = 4;\n\tbytes readTimeoutJSON = 5;\n\tbytes connTimeoutJSON = 6;\n\tint32 poolSize = 7;\n\tstring pathInfoPattern = 8;\n}",
@@ -20879,12 +21694,12 @@
},
{
"name": "InstallNSNodeRequest",
- "code": "message InstallNSNodeRequest {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message InstallNSNodeRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": "安装NS节点"
},
{
"name": "InstallNSNodeResponse",
- "code": "message InstallNSNodeResponse {\n\n}",
+ "code": "message InstallNSNodeResponse {\r\n\r\n}",
"doc": ""
},
{
@@ -21209,12 +22024,12 @@
},
{
"name": "ListEnabledUsersRequest",
- "code": "message ListEnabledUsersRequest {\n\tstring keyword = 1;\n\tbool isVerifying = 4;\n\tint32 mobileIsVerified = 5; // 手机号是否已验证,1表示已验证,0表示未验证,-1表示所有状态\n\tint64 offset = 2;\n\tint64 size = 3;\n}",
+ "code": "message ListEnabledUsersRequest {\r\n\tstring keyword = 1;\r\n\tbool isVerifying = 4;\r\n\tint32 mobileIsVerified = 5; // 手机号是否已验证,1表示已验证,0表示未验证,-1表示所有状态\r\n\tint64 offset = 2;\r\n\tint64 size = 3;\r\n}",
"doc": "列出单页用户"
},
{
"name": "ListEnabledUsersResponse",
- "code": "message ListEnabledUsersResponse {\n\trepeated User users = 1;\n}",
+ "code": "message ListEnabledUsersResponse {\r\n\trepeated User users = 1;\r\n}",
"doc": ""
},
{
@@ -21239,12 +22054,12 @@
},
{
"name": "ListHTTPAccessLogPoliciesRequest",
- "code": "message ListHTTPAccessLogPoliciesRequest {\n\tint64 offset = 1;\n\tint64 size = 2;\n}",
+ "code": "message ListHTTPAccessLogPoliciesRequest {\r\n\tint64 offset = 1;\r\n\tint64 size = 2;\r\n}",
"doc": "列出单页访问日志策略"
},
{
"name": "ListHTTPAccessLogPoliciesResponse",
- "code": "message ListHTTPAccessLogPoliciesResponse {\n\trepeated HTTPAccessLogPolicy httpAccessLogPolicies = 1;\n}",
+ "code": "message ListHTTPAccessLogPoliciesResponse {\r\n\trepeated HTTPAccessLogPolicy httpAccessLogPolicies = 1;\r\n}",
"doc": ""
},
{
@@ -21267,6 +22082,86 @@
"code": "message ListHTTPCacheTasksResponse {\n\trepeated HTTPCacheTask httpCacheTasks = 1; // 一组任务信息\n}",
"doc": ""
},
+ {
+ "name": "ListHTTPDNSAccessLogsRequest",
+ "code": "message ListHTTPDNSAccessLogsRequest {\r\n\tstring day = 1;\r\n\tint64 clusterId = 2;\r\n\tint64 nodeId = 3;\r\n\tstring appId = 4;\r\n\tstring domain = 5;\r\n\tstring status = 6;\r\n\tstring keyword = 7;\r\n\tint64 offset = 8;\r\n\tint64 size = 9;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSAccessLogsResponse",
+ "code": "message ListHTTPDNSAccessLogsResponse {\r\n\trepeated HTTPDNSAccessLog logs = 1;\r\n\tint64 total = 2;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSAppsRequest",
+ "code": "message ListHTTPDNSAppsRequest {\r\n\tint64 offset = 1;\r\n\tint64 size = 2;\r\n\tstring keyword = 3;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSAppsResponse",
+ "code": "message ListHTTPDNSAppsResponse {\r\n\trepeated HTTPDNSApp apps = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSClustersRequest",
+ "code": "message ListHTTPDNSClustersRequest {\r\n\tint64 offset = 1;\r\n\tint64 size = 2;\r\n\tstring keyword = 3;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSClustersResponse",
+ "code": "message ListHTTPDNSClustersResponse {\r\n\trepeated HTTPDNSCluster clusters = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSCustomRulesWithDomainIdRequest",
+ "code": "message ListHTTPDNSCustomRulesWithDomainIdRequest {\r\n\tint64 domainId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSCustomRulesWithDomainIdResponse",
+ "code": "message ListHTTPDNSCustomRulesWithDomainIdResponse {\r\n\trepeated HTTPDNSCustomRule rules = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSDomainsWithAppIdRequest",
+ "code": "message ListHTTPDNSDomainsWithAppIdRequest {\r\n\tint64 appDbId = 1;\r\n\tstring keyword = 2;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSDomainsWithAppIdResponse",
+ "code": "message ListHTTPDNSDomainsWithAppIdResponse {\r\n\trepeated HTTPDNSDomain domains = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSNodesRequest",
+ "code": "message ListHTTPDNSNodesRequest {\r\n\tint64 clusterId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSNodesResponse",
+ "code": "message ListHTTPDNSNodesResponse {\r\n\trepeated HTTPDNSNode nodes = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSNodesWithClusterIdRequest",
+ "code": "message ListHTTPDNSNodesWithClusterIdRequest {\r\n\tint64 clusterId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSNodesWithClusterIdResponse",
+ "code": "message ListHTTPDNSNodesWithClusterIdResponse {\r\n\trepeated HTTPDNSNode nodes = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSRuntimeLogsRequest",
+ "code": "message ListHTTPDNSRuntimeLogsRequest {\r\n\tstring day = 1;\r\n\tint64 clusterId = 2;\r\n\tint64 nodeId = 3;\r\n\tstring level = 4;\r\n\tstring keyword = 5;\r\n\tint64 offset = 6;\r\n\tint64 size = 7;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ListHTTPDNSRuntimeLogsResponse",
+ "code": "message ListHTTPDNSRuntimeLogsResponse {\r\n\trepeated HTTPDNSRuntimeLog logs = 1;\r\n\tint64 total = 2;\r\n}",
+ "doc": ""
+ },
{
"name": "ListIPItemsAfterVersionRequest",
"code": "message ListIPItemsAfterVersionRequest {\n\tint64 version = 1; // 版本号\n\tint64 size = 2; // 数量\n}",
@@ -21384,12 +22279,12 @@
},
{
"name": "ListNSNodesMatchRequest",
- "code": "message ListNSNodesMatchRequest {\n\tint64 offset = 1;\n\tint64 size = 2;\n\tint64 nsClusterId = 3;\n\tint32 installState = 4;\n\tint32 activeState = 5;\n\tstring keyword = 6;\n\t//int64 nodeGroupId = 7;\n\t//int64 nodeRegionId = 8;\n}",
+ "code": "message ListNSNodesMatchRequest {\r\n\tint64 offset = 1;\r\n\tint64 size = 2;\r\n\tint64 nsClusterId = 3;\r\n\tint32 installState = 4;\r\n\tint32 activeState = 5;\r\n\tstring keyword = 6;\r\n\t//int64 nodeGroupId = 7;\r\n\t//int64 nodeRegionId = 8;\r\n}",
"doc": "列出单页NS节点"
},
{
"name": "ListNSNodesMatchResponse",
- "code": "message ListNSNodesMatchResponse {\n\trepeated NSNode nsNodes = 1;\n}",
+ "code": "message ListNSNodesMatchResponse {\r\n\trepeated NSNode nsNodes = 1;\r\n}",
"doc": ""
},
{
@@ -21694,12 +22589,12 @@
},
{
"name": "LoginUserRequest",
- "code": "message LoginUserRequest {\n\tstring username = 1;\n\tstring password = 2;\n}",
+ "code": "message LoginUserRequest {\r\n\tstring username = 1;\r\n\tstring password = 2;\r\n}",
"doc": "登录"
},
{
"name": "LoginUserResponse",
- "code": "message LoginUserResponse {\n\tint64 userId = 1;\n\tbool isOk = 2;\n\tstring message = 3;\n}",
+ "code": "message LoginUserResponse {\r\n\tint64 userId = 1;\r\n\tbool isOk = 2;\r\n\tstring message = 3;\r\n}",
"doc": ""
},
{
@@ -21819,7 +22714,7 @@
},
{
"name": "NSNodeStreamMessage",
- "code": "message NSNodeStreamMessage {\n\tint64 nsNodeId = 1;\n\tint64 requestId = 2;\n\tint32 timeoutSeconds = 3;\n\tstring code = 4;\n\tbytes dataJSON = 5;\n\tbool isOk = 6;\n\tstring message = 7;\n}",
+ "code": "message NSNodeStreamMessage {\r\n\tint64 nsNodeId = 1;\r\n\tint64 requestId = 2;\r\n\tint32 timeoutSeconds = 3;\r\n\tstring code = 4;\r\n\tbytes dataJSON = 5;\r\n\tbool isOk = 6;\r\n\tstring message = 7;\r\n}",
"doc": "NS节点stream"
},
{
@@ -22129,12 +23024,12 @@
},
{
"name": "RegisterUserRequest",
- "code": "message RegisterUserRequest {\n\tstring username = 1;\n\tstring password = 2;\n\tstring mobile = 3;\n\tstring email = 4;\n\tstring fullname = 5;\n\tstring ip = 6;\n\tstring source = 7;\n}",
+ "code": "message RegisterUserRequest {\r\n\tstring username = 1;\r\n\tstring password = 2;\r\n\tstring mobile = 3;\r\n\tstring email = 4;\r\n\tstring fullname = 5;\r\n\tstring ip = 6;\r\n\tstring source = 7;\r\n}",
"doc": "注册用户"
},
{
"name": "RegisterUserResponse",
- "code": "message RegisterUserResponse {\n\tint64 userId = 1;\n\tbool requireEmailVerification = 2; // 是否需要激活邮件\n}",
+ "code": "message RegisterUserResponse {\r\n\tint64 userId = 1;\r\n\tbool requireEmailVerification = 2; // 是否需要激活邮件\r\n}",
"doc": ""
},
{
@@ -22164,12 +23059,12 @@
},
{
"name": "RenewUserServersStateRequest",
- "code": "message RenewUserServersStateRequest {\n\tint64 userId = 1;\n}",
+ "code": "message RenewUserServersStateRequest {\r\n\tint64 userId = 1;\r\n}",
"doc": "更新用户服务可用状态"
},
{
"name": "RenewUserServersStateResponse",
- "code": "message RenewUserServersStateResponse {\n\tbool isEnabled = 1;\n}",
+ "code": "message RenewUserServersStateResponse {\r\n\tbool isEnabled = 1;\r\n}",
"doc": ""
},
{
@@ -22207,6 +23102,16 @@
"code": "message ResetHTTPCacheTaskRequest {\n\tint64 httpCacheTaskId = 1; // 任务ID\n}",
"doc": "重置任务状态"
},
+ {
+ "name": "ResetHTTPDNSAppSignSecretRequest",
+ "code": "message ResetHTTPDNSAppSignSecretRequest {\r\n\tint64 appDbId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "ResetHTTPDNSAppSignSecretResponse",
+ "code": "message ResetHTTPDNSAppSignSecretResponse {\r\n\tstring signSecret = 1;\r\n\tint64 updatedAt = 2;\r\n}",
+ "doc": ""
+ },
{
"name": "ResetNodeActionStatusRequest",
"code": "message ResetNodeActionStatusRequest {\n\tint64 nodeId = 1; // 节点ID\n}",
@@ -22374,12 +23279,12 @@
},
{
"name": "StartNSNodeRequest",
- "code": "message StartNSNodeRequest {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message StartNSNodeRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": "启动NS节点"
},
{
"name": "StartNSNodeResponse",
- "code": "message StartNSNodeResponse {\n\tbool isOk = 1;\n\tstring error = 2;\n}",
+ "code": "message StartNSNodeResponse {\r\n\tbool isOk = 1;\r\n\tstring error = 2;\r\n}",
"doc": ""
},
{
@@ -22394,12 +23299,12 @@
},
{
"name": "StopNSNodeRequest",
- "code": "message StopNSNodeRequest {\n\tint64 nsNodeId = 1;\n}",
+ "code": "message StopNSNodeRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
"doc": "停止NS节点"
},
{
"name": "StopNSNodeResponse",
- "code": "message StopNSNodeResponse {\n\tbool isOk = 1;\n\tstring error = 2;\n}",
+ "code": "message StopNSNodeResponse {\r\n\tbool isOk = 1;\r\n\tstring error = 2;\r\n}",
"doc": ""
},
{
@@ -22517,6 +23422,16 @@
"code": "message SysLockerUnlockRequest {\n\tstring key = 1;\n}",
"doc": "释放锁"
},
+ {
+ "name": "TestHTTPDNSResolveRequest",
+ "code": "message TestHTTPDNSResolveRequest {\r\n\tint64 clusterId = 1;\r\n\tstring appId = 2;\r\n\tstring domain = 3;\r\n\tstring qtype = 4;\r\n\tstring clientIP = 5;\r\n\tstring sid = 6;\r\n\tstring sdkVersion = 7;\r\n\tstring os = 8;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "TestHTTPDNSResolveResponse",
+ "code": "message TestHTTPDNSResolveResponse {\r\n\tstring code = 1;\r\n\tstring message = 2;\r\n\tstring requestId = 3;\r\n\tstring domain = 4;\r\n\tstring qtype = 5;\r\n\tint32 ttl = 6;\r\n\trepeated HTTPDNSResolveRecord records = 7;\r\n\tstring clientIP = 8;\r\n\tstring clientRegion = 9;\r\n\tstring clientCarrier = 10;\r\n\tstring clientCountry = 11;\r\n\tstring summary = 12;\r\n}",
+ "doc": ""
+ },
{
"name": "TestNodeGrantRequest",
"code": "message TestNodeGrantRequest {\n\tint64 nodeGrantId = 1;\n\tstring host = 2;\n\tint32 port = 3;\n}",
@@ -22654,7 +23569,7 @@
},
{
"name": "UpdateAllUsersFeaturesRequest",
- "code": "message UpdateAllUsersFeaturesRequest {\n\trepeated string featureCodes = 1;\n\tbool overwrite = 2;\n}",
+ "code": "message UpdateAllUsersFeaturesRequest {\r\n\trepeated string featureCodes = 1;\r\n\tbool overwrite = 2;\r\n}",
"doc": "设置所有用户能使用的功能"
},
{
@@ -22694,7 +23609,7 @@
},
{
"name": "UpdateHTTPAccessLogPolicyRequest",
- "code": "message UpdateHTTPAccessLogPolicyRequest {\n\tint64 httpAccessLogPolicyId = 1;\n\tstring name = 2;\n\tbool isOn = 3;\n\tbytes optionsJSON = 4;\n\tbytes condsJSON = 5;\n\tbool isPublic = 6;\n\tbool firewallOnly = 7;\n\tbool disableDefaultDB = 8;\n}",
+ "code": "message UpdateHTTPAccessLogPolicyRequest {\r\n\tint64 httpAccessLogPolicyId = 1;\r\n\tstring name = 2;\r\n\tstring type = 10; // 存储类型:file / es / tcp / syslog / command\r\n\tbool isOn = 3;\r\n\tbytes optionsJSON = 4;\r\n\tbytes condsJSON = 5;\r\n\tbool isPublic = 6;\r\n\tbool firewallOnly = 7;\r\n\tbool disableDefaultDB = 8;\r\n\tbytes writeTargetsJSON = 9;\r\n}",
"doc": "修改访问日志策略"
},
{
@@ -22717,6 +23632,56 @@
"code": "message UpdateHTTPCacheTaskKeysStatusRequest {\n\trepeated KeyResult keyResults = 1;\n\n\n\tmessage KeyResult {\n\t\tint64 id = 1;\n\t\tint64 nodeClusterId = 2; // 特意设置的冗余数据\n\t\tstring error = 3;\n\t}\n}",
"doc": "更新一组Key状态"
},
+ {
+ "name": "UpdateHTTPDNSAppRequest",
+ "code": "message UpdateHTTPDNSAppRequest {\r\n\tint64 appDbId = 1;\r\n\tstring name = 2;\r\n\treserved 3, 4; // removed: primaryClusterId, backupClusterId\r\n\tbool isOn = 5;\r\n\tint64 userId = 6;\r\n\tbytes clusterIdsJSON = 7;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "UpdateHTTPDNSAppSignEnabledRequest",
+ "code": "message UpdateHTTPDNSAppSignEnabledRequest {\r\n\tint64 appDbId = 1;\r\n\tbool signEnabled = 2;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "UpdateHTTPDNSClusterDefaultRequest",
+ "code": "message UpdateHTTPDNSClusterDefaultRequest {\r\n\tint64 clusterId = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "UpdateHTTPDNSClusterRequest",
+ "code": "message UpdateHTTPDNSClusterRequest {\r\n\tint64 clusterId = 1;\r\n\tstring name = 2;\r\n\tstring serviceDomain = 3;\r\n\tint32 defaultTTL = 4;\r\n\tint32 fallbackTimeoutMs = 5;\r\n\tstring installDir = 6;\r\n\tbytes tlsPolicyJSON = 7;\r\n\tbool isOn = 8;\r\n\tbool isDefault = 9;\r\n\tbool autoRemoteStart = 10;\r\n\tbool accessLogIsOn = 11;\r\n\tstring timeZone = 12;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "UpdateHTTPDNSCustomRuleRequest",
+ "code": "message UpdateHTTPDNSCustomRuleRequest {\r\n\tHTTPDNSCustomRule rule = 1;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "UpdateHTTPDNSCustomRuleStatusRequest",
+ "code": "message UpdateHTTPDNSCustomRuleStatusRequest {\r\n\tint64 ruleId = 1;\r\n\tbool isOn = 2;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "UpdateHTTPDNSDomainStatusRequest",
+ "code": "message UpdateHTTPDNSDomainStatusRequest {\r\n\tint64 domainId = 1;\r\n\tbool isOn = 2;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "UpdateHTTPDNSNodeLoginRequest",
+ "code": "message UpdateHTTPDNSNodeLoginRequest {\r\n\tint64 nodeId = 1;\r\n\tNodeLogin nodeLogin = 2;\r\n}",
+ "doc": "修改HTTPDNS节点登录信息"
+ },
+ {
+ "name": "UpdateHTTPDNSNodeRequest",
+ "code": "message UpdateHTTPDNSNodeRequest {\r\n\tint64 nodeId = 1;\r\n\tstring name = 2;\r\n\tstring installDir = 3;\r\n\tbool isOn = 4;\r\n}",
+ "doc": ""
+ },
+ {
+ "name": "UpdateHTTPDNSNodeStatusRequest",
+ "code": "message UpdateHTTPDNSNodeStatusRequest {\r\n\tint64 nodeId = 1;\r\n\tbool isUp = 2;\r\n\tbool isInstalled = 3;\r\n\tbool isActive = 4;\r\n\tbytes statusJSON = 5;\r\n\tbytes installStatusJSON = 6;\r\n}",
+ "doc": ""
+ },
{
"name": "UpdateHTTPFastcgiRequest",
"code": "message UpdateHTTPFastcgiRequest {\n\tint64 httpFastcgiId = 1;\n\tbool isOn = 2;\n\tstring address = 3;\n\tbytes paramsJSON = 4;\n\tbytes readTimeoutJSON = 5;\n\tbytes connTimeoutJSON = 6;\n\tint32 poolSize = 7;\n\tstring pathInfoPattern = 8;\n}",
@@ -23134,37 +24099,37 @@
},
{
"name": "UpdateNSNodeAPIConfigRequest",
- "code": "message UpdateNSNodeAPIConfigRequest {\n\tint64 nsNodeId = 1;\n\tbytes apiNodeAddrsJSON = 2;\n}",
+ "code": "message UpdateNSNodeAPIConfigRequest {\r\n\tint64 nsNodeId = 1;\r\n\tbytes apiNodeAddrsJSON = 2;\r\n}",
"doc": "修改某个节点的API相关配置"
},
{
"name": "UpdateNSNodeConnectedAPINodesRequest",
- "code": "message UpdateNSNodeConnectedAPINodesRequest {\n\trepeated int64 apiNodeIds = 1;\n}",
+ "code": "message UpdateNSNodeConnectedAPINodesRequest {\r\n\trepeated int64 apiNodeIds = 1;\r\n}",
"doc": "更改NS节点连接的API节点信息"
},
{
"name": "UpdateNSNodeDDoSProtectionRequest",
- "code": "message UpdateNSNodeDDoSProtectionRequest {\n\tint64 nsNodeId = 1;\n\tbytes ddosProtectionJSON = 2;\n}",
+ "code": "message UpdateNSNodeDDoSProtectionRequest {\r\n\tint64 nsNodeId = 1;\r\n\tbytes ddosProtectionJSON = 2;\r\n}",
"doc": "修改NS节点的DDoS设置"
},
{
"name": "UpdateNSNodeIsInstalledRequest",
- "code": "message UpdateNSNodeIsInstalledRequest {\n\tint64 nsNodeId = 1;\n\tbool isInstalled = 2;\n}",
+ "code": "message UpdateNSNodeIsInstalledRequest {\r\n\tint64 nsNodeId = 1;\r\n\tbool isInstalled = 2;\r\n}",
"doc": "修改NS节点安装状态"
},
{
"name": "UpdateNSNodeLoginRequest",
- "code": "message UpdateNSNodeLoginRequest {\n\tint64 nsNodeId = 1;\n\tNodeLogin nodeLogin = 2;\n}",
+ "code": "message UpdateNSNodeLoginRequest {\r\n\tint64 nsNodeId = 1;\r\n\tNodeLogin nodeLogin = 2;\r\n}",
"doc": "修改NS节点登录信息"
},
{
"name": "UpdateNSNodeRequest",
- "code": "message UpdateNSNodeRequest {\n\tint64 nsNodeId = 1;\n\tstring name = 2;\n\tint64 nsClusterId = 3;\n\tNodeLogin nodeLogin = 4;\n\tbool isOn = 6;\n}",
+ "code": "message UpdateNSNodeRequest {\r\n\tint64 nsNodeId = 1;\r\n\tstring name = 2;\r\n\tint64 nsClusterId = 3;\r\n\tNodeLogin nodeLogin = 4;\r\n\tbool isOn = 6;\r\n}",
"doc": "修改NS节点"
},
{
"name": "UpdateNSNodeStatusRequest",
- "code": "message UpdateNSNodeStatusRequest {\n\tint64 nodeId = 1;\n\tbytes statusJSON = 2;\n}",
+ "code": "message UpdateNSNodeStatusRequest {\r\n\tint64 nodeId = 1;\r\n\tbytes statusJSON = 2;\r\n}",
"doc": "更新NS节点状态"
},
{
@@ -23734,7 +24699,7 @@
},
{
"name": "UpdateUserFeaturesRequest",
- "code": "message UpdateUserFeaturesRequest {\n\tint64 userId = 1;\n\trepeated string featureCodes = 2;\n}",
+ "code": "message UpdateUserFeaturesRequest {\r\n\tint64 userId = 1;\r\n\trepeated string featureCodes = 2;\r\n}",
"doc": "设置单个用户能使用的功能"
},
{
@@ -23744,12 +24709,12 @@
},
{
"name": "UpdateUserInfoRequest",
- "code": "message UpdateUserInfoRequest {\n\tint64 userId = 1;\n\tstring fullname = 2;\n\tstring mobile = 3;\n\tstring email = 4;\n}",
+ "code": "message UpdateUserInfoRequest {\r\n\tint64 userId = 1;\r\n\tstring fullname = 2;\r\n\tstring mobile = 3;\r\n\tstring email = 4;\r\n}",
"doc": "修改用户基本信息"
},
{
"name": "UpdateUserLoginRequest",
- "code": "message UpdateUserLoginRequest {\n\tint64 userId = 1;\n\tstring username = 2;\n\tstring password = 3;\n}",
+ "code": "message UpdateUserLoginRequest {\r\n\tint64 userId = 1;\r\n\tstring username = 2;\r\n\tstring password = 3;\r\n}",
"doc": "修改用户登录信息"
},
{
@@ -23769,17 +24734,17 @@
},
{
"name": "UpdateUserPricePeriodRequest",
- "code": "message UpdateUserPricePeriodRequest {\n\tint64 userId = 1;\n\tstring pricePeriod = 2;\n}",
+ "code": "message UpdateUserPricePeriodRequest {\r\n\tint64 userId = 1;\r\n\tstring pricePeriod = 2;\r\n}",
"doc": "修改用户计费周期"
},
{
"name": "UpdateUserPriceTypeRequest",
- "code": "message UpdateUserPriceTypeRequest {\n\tint64 userId = 1;\n\tstring priceType = 2;\n}",
+ "code": "message UpdateUserPriceTypeRequest {\r\n\tint64 userId = 1;\r\n\tstring priceType = 2;\r\n}",
"doc": "修改用户计费方式"
},
{
"name": "UpdateUserRequest",
- "code": "message UpdateUserRequest {\n\tint64 userId = 1;\n\tstring username = 2;\n\tstring password = 3;\n\tstring fullname = 4;\n\tstring mobile = 5;\n\tstring tel = 6;\n\tstring email = 7;\n\tstring remark = 8;\n\tbool isOn = 9;\n\tint64 nodeClusterId = 10;\n\tstring bandwidthAlgo = 11;\n}",
+ "code": "message UpdateUserRequest {\r\n\tint64 userId = 1;\r\n\tstring username = 2;\r\n\tstring password = 3;\r\n\tstring fullname = 4;\r\n\tstring mobile = 5;\r\n\tstring tel = 6;\r\n\tstring email = 7;\r\n\tstring remark = 8;\r\n\tbool isOn = 9;\r\n\tint64 nodeClusterId = 10;\r\n\tstring bandwidthAlgo = 11;\r\n\tbytes httpdnsClusterIdsJSON = 12; // HTTPDNS关联集群ID列表\r\n}",
"doc": "修改用户"
},
{
@@ -23792,6 +24757,16 @@
"code": "message UpdateUserTicketRequest {\n\tint64 userTicketId = 1;\n\tint64 userTicketCategoryId = 2;\n\tstring subject = 3;\n\tstring body = 4;\n}",
"doc": "修改工单"
},
+ {
+ "name": "UpgradeHTTPDNSNodeRequest",
+ "code": "message UpgradeHTTPDNSNodeRequest {\r\n\tint64 nodeId = 1;\r\n}",
+ "doc": "升级单个HTTPDNS节点"
+ },
+ {
+ "name": "UpgradeNSNodeRequest",
+ "code": "message UpgradeNSNodeRequest {\r\n\tint64 nsNodeId = 1;\r\n}",
+ "doc": "升级单个NS节点"
+ },
{
"name": "UpgradeNodeRequest",
"code": "message UpgradeNodeRequest {\n\tint64 nodeId = 1;\n}",
@@ -23849,7 +24824,7 @@
},
{
"name": "User",
- "code": "message User {\n\tint64 id = 1; // 用户ID\n\tstring username = 2; // 用户名\n\tstring fullname = 3; // 全称\n\tstring mobile = 4; // 手机号码\n\tstring tel = 5; // 联系电话\n\tstring email = 6; // 联系邮箱\n\tstring verifiedEmail = 20; // 已验证邮箱\n\tstring verifiedMobile = 23; // 已验证手机号码\n\tstring remark = 7; // 备注\n\tbool isOn = 8; // 是否启用\n\tint64 createdAt = 9; // 创建时间\n\tstring registeredIP = 12; // 注册IP\n\tbool isVerified = 13; // 是否已实名认证\n\tbool isRejected = 14; // 实名认证是否已拒绝\n\tstring rejectReason = 15; // 实名认证拒绝理由\n\tbool isDeleted = 16; // 是否已删除\n\tbool isIndividualIdentified = 17; // 是否已通过个人验证\n\tbool isEnterpriseIdentified = 18; // 是否已通过企业验证\n\tstring bandwidthAlgo = 21; // 带宽算法\n\tstring lang = 22; // 语言代号\n\n\tLogin otpLogin = 19; // OTP认证\n\n\tNodeCluster nodeCluster = 10; // 集群信息\n\trepeated UserFeature features = 11; // 开通功能\n}",
+ "code": "message User {\r\n\tint64 id = 1; // 用户ID\r\n\tstring username = 2; // 用户名\r\n\tstring fullname = 3; // 全称\r\n\tstring mobile = 4; // 手机号码\r\n\tstring tel = 5; // 联系电话\r\n\tstring email = 6; // 联系邮箱\r\n\tstring verifiedEmail = 20; // 已验证邮箱\r\n\tstring verifiedMobile = 23; // 已验证手机号码\r\n\tstring remark = 7; // 备注\r\n\tbool isOn = 8; // 是否启用\r\n\tint64 createdAt = 9; // 创建时间\r\n\tstring registeredIP = 12; // 注册IP\r\n\tbool isVerified = 13; // 是否已实名认证\r\n\tbool isRejected = 14; // 实名认证是否已拒绝\r\n\tstring rejectReason = 15; // 实名认证拒绝理由\r\n\tbool isDeleted = 16; // 是否已删除\r\n\tbool isIndividualIdentified = 17; // 是否已通过个人验证\r\n\tbool isEnterpriseIdentified = 18; // 是否已通过企业验证\r\n\tstring bandwidthAlgo = 21; // 带宽算法\r\n\tstring lang = 22; // 语言代号\r\n\tbytes httpdnsClusterIdsJSON = 24; // HTTPDNS关联集群ID列表\r\n\r\n\tLogin otpLogin = 19; // OTP认证\r\n\r\n\tNodeCluster nodeCluster = 10; // 集群信息\r\n\trepeated UserFeature features = 11; // 开通功能\r\n}",
"doc": ""
},
{
@@ -24009,12 +24984,12 @@
},
{
"name": "VerifyUserRequest",
- "code": "message VerifyUserRequest {\n\tint64 userId = 1;\n\tbool isRejected = 2;\n\tstring rejectReason = 3;\n}",
+ "code": "message VerifyUserRequest {\r\n\tint64 userId = 1;\r\n\tbool isRejected = 2;\r\n\tstring rejectReason = 3;\r\n}",
"doc": "审核用户"
},
{
"name": "WriteHTTPAccessLogPolicyRequest",
- "code": "message WriteHTTPAccessLogPolicyRequest {\n\tint64 httpAccessLogPolicyId = 1;\n\tHTTPAccessLog httpAccessLog = 2;\n}",
+ "code": "message WriteHTTPAccessLogPolicyRequest {\r\n\tint64 httpAccessLogPolicyId = 1;\r\n\tHTTPAccessLog httpAccessLog = 2;\r\n}",
"doc": "测试写入某个访问日志策略"
},
{
diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_board.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_board.pb.go
new file mode 100644
index 0000000..5a6cf00
--- /dev/null
+++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_board.pb.go
@@ -0,0 +1,650 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.36.11
+// protoc v3.12.4
+// source: service_httpdns_board.proto
+
+package pb
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+ unsafe "unsafe"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// 组合看板数据请求
+type ComposeHTTPDNSBoardRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *ComposeHTTPDNSBoardRequest) Reset() {
+ *x = ComposeHTTPDNSBoardRequest{}
+ mi := &file_service_httpdns_board_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *ComposeHTTPDNSBoardRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ComposeHTTPDNSBoardRequest) ProtoMessage() {}
+
+func (x *ComposeHTTPDNSBoardRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_service_httpdns_board_proto_msgTypes[0]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ComposeHTTPDNSBoardRequest.ProtoReflect.Descriptor instead.
+func (*ComposeHTTPDNSBoardRequest) Descriptor() ([]byte, []int) {
+ return file_service_httpdns_board_proto_rawDescGZIP(), []int{0}
+}
+
+// 组合看板数据响应
+type ComposeHTTPDNSBoardResponse struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ CountApps int64 `protobuf:"varint,1,opt,name=countApps,proto3" json:"countApps,omitempty"`
+ CountDomains int64 `protobuf:"varint,2,opt,name=countDomains,proto3" json:"countDomains,omitempty"`
+ CountClusters int64 `protobuf:"varint,3,opt,name=countClusters,proto3" json:"countClusters,omitempty"`
+ CountNodes int64 `protobuf:"varint,4,opt,name=countNodes,proto3" json:"countNodes,omitempty"`
+ CountOfflineNodes int64 `protobuf:"varint,5,opt,name=countOfflineNodes,proto3" json:"countOfflineNodes,omitempty"`
+ DailyTrafficStats []*ComposeHTTPDNSBoardResponse_DailyTrafficStat `protobuf:"bytes,30,rep,name=dailyTrafficStats,proto3" json:"dailyTrafficStats,omitempty"`
+ HourlyTrafficStats []*ComposeHTTPDNSBoardResponse_HourlyTrafficStat `protobuf:"bytes,31,rep,name=hourlyTrafficStats,proto3" json:"hourlyTrafficStats,omitempty"`
+ TopAppStats []*ComposeHTTPDNSBoardResponse_TopAppStat `protobuf:"bytes,32,rep,name=topAppStats,proto3" json:"topAppStats,omitempty"`
+ TopDomainStats []*ComposeHTTPDNSBoardResponse_TopDomainStat `protobuf:"bytes,33,rep,name=topDomainStats,proto3" json:"topDomainStats,omitempty"`
+ TopNodeStats []*ComposeHTTPDNSBoardResponse_TopNodeStat `protobuf:"bytes,34,rep,name=topNodeStats,proto3" json:"topNodeStats,omitempty"`
+ CpuNodeValues []*NodeValue `protobuf:"bytes,35,rep,name=cpuNodeValues,proto3" json:"cpuNodeValues,omitempty"`
+ MemoryNodeValues []*NodeValue `protobuf:"bytes,36,rep,name=memoryNodeValues,proto3" json:"memoryNodeValues,omitempty"`
+ LoadNodeValues []*NodeValue `protobuf:"bytes,37,rep,name=loadNodeValues,proto3" json:"loadNodeValues,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *ComposeHTTPDNSBoardResponse) Reset() {
+ *x = ComposeHTTPDNSBoardResponse{}
+ mi := &file_service_httpdns_board_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *ComposeHTTPDNSBoardResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ComposeHTTPDNSBoardResponse) ProtoMessage() {}
+
+func (x *ComposeHTTPDNSBoardResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_service_httpdns_board_proto_msgTypes[1]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ComposeHTTPDNSBoardResponse.ProtoReflect.Descriptor instead.
+func (*ComposeHTTPDNSBoardResponse) Descriptor() ([]byte, []int) {
+ return file_service_httpdns_board_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetCountApps() int64 {
+ if x != nil {
+ return x.CountApps
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetCountDomains() int64 {
+ if x != nil {
+ return x.CountDomains
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetCountClusters() int64 {
+ if x != nil {
+ return x.CountClusters
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetCountNodes() int64 {
+ if x != nil {
+ return x.CountNodes
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetCountOfflineNodes() int64 {
+ if x != nil {
+ return x.CountOfflineNodes
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetDailyTrafficStats() []*ComposeHTTPDNSBoardResponse_DailyTrafficStat {
+ if x != nil {
+ return x.DailyTrafficStats
+ }
+ return nil
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetHourlyTrafficStats() []*ComposeHTTPDNSBoardResponse_HourlyTrafficStat {
+ if x != nil {
+ return x.HourlyTrafficStats
+ }
+ return nil
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetTopAppStats() []*ComposeHTTPDNSBoardResponse_TopAppStat {
+ if x != nil {
+ return x.TopAppStats
+ }
+ return nil
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetTopDomainStats() []*ComposeHTTPDNSBoardResponse_TopDomainStat {
+ if x != nil {
+ return x.TopDomainStats
+ }
+ return nil
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetTopNodeStats() []*ComposeHTTPDNSBoardResponse_TopNodeStat {
+ if x != nil {
+ return x.TopNodeStats
+ }
+ return nil
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetCpuNodeValues() []*NodeValue {
+ if x != nil {
+ return x.CpuNodeValues
+ }
+ return nil
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetMemoryNodeValues() []*NodeValue {
+ if x != nil {
+ return x.MemoryNodeValues
+ }
+ return nil
+}
+
+func (x *ComposeHTTPDNSBoardResponse) GetLoadNodeValues() []*NodeValue {
+ if x != nil {
+ return x.LoadNodeValues
+ }
+ return nil
+}
+
+type ComposeHTTPDNSBoardResponse_DailyTrafficStat struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Day string `protobuf:"bytes,1,opt,name=day,proto3" json:"day,omitempty"`
+ Bytes int64 `protobuf:"varint,2,opt,name=bytes,proto3" json:"bytes,omitempty"`
+ CountRequests int64 `protobuf:"varint,3,opt,name=countRequests,proto3" json:"countRequests,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *ComposeHTTPDNSBoardResponse_DailyTrafficStat) Reset() {
+ *x = ComposeHTTPDNSBoardResponse_DailyTrafficStat{}
+ mi := &file_service_httpdns_board_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *ComposeHTTPDNSBoardResponse_DailyTrafficStat) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ComposeHTTPDNSBoardResponse_DailyTrafficStat) ProtoMessage() {}
+
+func (x *ComposeHTTPDNSBoardResponse_DailyTrafficStat) ProtoReflect() protoreflect.Message {
+ mi := &file_service_httpdns_board_proto_msgTypes[2]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ComposeHTTPDNSBoardResponse_DailyTrafficStat.ProtoReflect.Descriptor instead.
+func (*ComposeHTTPDNSBoardResponse_DailyTrafficStat) Descriptor() ([]byte, []int) {
+ return file_service_httpdns_board_proto_rawDescGZIP(), []int{1, 0}
+}
+
+func (x *ComposeHTTPDNSBoardResponse_DailyTrafficStat) GetDay() string {
+ if x != nil {
+ return x.Day
+ }
+ return ""
+}
+
+func (x *ComposeHTTPDNSBoardResponse_DailyTrafficStat) GetBytes() int64 {
+ if x != nil {
+ return x.Bytes
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_DailyTrafficStat) GetCountRequests() int64 {
+ if x != nil {
+ return x.CountRequests
+ }
+ return 0
+}
+
+type ComposeHTTPDNSBoardResponse_HourlyTrafficStat struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Hour string `protobuf:"bytes,1,opt,name=hour,proto3" json:"hour,omitempty"`
+ Bytes int64 `protobuf:"varint,2,opt,name=bytes,proto3" json:"bytes,omitempty"`
+ CountRequests int64 `protobuf:"varint,3,opt,name=countRequests,proto3" json:"countRequests,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *ComposeHTTPDNSBoardResponse_HourlyTrafficStat) Reset() {
+ *x = ComposeHTTPDNSBoardResponse_HourlyTrafficStat{}
+ mi := &file_service_httpdns_board_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *ComposeHTTPDNSBoardResponse_HourlyTrafficStat) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ComposeHTTPDNSBoardResponse_HourlyTrafficStat) ProtoMessage() {}
+
+func (x *ComposeHTTPDNSBoardResponse_HourlyTrafficStat) ProtoReflect() protoreflect.Message {
+ mi := &file_service_httpdns_board_proto_msgTypes[3]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ComposeHTTPDNSBoardResponse_HourlyTrafficStat.ProtoReflect.Descriptor instead.
+func (*ComposeHTTPDNSBoardResponse_HourlyTrafficStat) Descriptor() ([]byte, []int) {
+ return file_service_httpdns_board_proto_rawDescGZIP(), []int{1, 1}
+}
+
+func (x *ComposeHTTPDNSBoardResponse_HourlyTrafficStat) GetHour() string {
+ if x != nil {
+ return x.Hour
+ }
+ return ""
+}
+
+func (x *ComposeHTTPDNSBoardResponse_HourlyTrafficStat) GetBytes() int64 {
+ if x != nil {
+ return x.Bytes
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_HourlyTrafficStat) GetCountRequests() int64 {
+ if x != nil {
+ return x.CountRequests
+ }
+ return 0
+}
+
+type ComposeHTTPDNSBoardResponse_TopAppStat struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ AppId int64 `protobuf:"varint,1,opt,name=appId,proto3" json:"appId,omitempty"`
+ AppName string `protobuf:"bytes,2,opt,name=appName,proto3" json:"appName,omitempty"`
+ CountRequests int64 `protobuf:"varint,3,opt,name=countRequests,proto3" json:"countRequests,omitempty"`
+ Bytes int64 `protobuf:"varint,4,opt,name=bytes,proto3" json:"bytes,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopAppStat) Reset() {
+ *x = ComposeHTTPDNSBoardResponse_TopAppStat{}
+ mi := &file_service_httpdns_board_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopAppStat) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ComposeHTTPDNSBoardResponse_TopAppStat) ProtoMessage() {}
+
+func (x *ComposeHTTPDNSBoardResponse_TopAppStat) ProtoReflect() protoreflect.Message {
+ mi := &file_service_httpdns_board_proto_msgTypes[4]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ComposeHTTPDNSBoardResponse_TopAppStat.ProtoReflect.Descriptor instead.
+func (*ComposeHTTPDNSBoardResponse_TopAppStat) Descriptor() ([]byte, []int) {
+ return file_service_httpdns_board_proto_rawDescGZIP(), []int{1, 2}
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopAppStat) GetAppId() int64 {
+ if x != nil {
+ return x.AppId
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopAppStat) GetAppName() string {
+ if x != nil {
+ return x.AppName
+ }
+ return ""
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopAppStat) GetCountRequests() int64 {
+ if x != nil {
+ return x.CountRequests
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopAppStat) GetBytes() int64 {
+ if x != nil {
+ return x.Bytes
+ }
+ return 0
+}
+
+type ComposeHTTPDNSBoardResponse_TopDomainStat struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ DomainId int64 `protobuf:"varint,1,opt,name=domainId,proto3" json:"domainId,omitempty"`
+ DomainName string `protobuf:"bytes,2,opt,name=domainName,proto3" json:"domainName,omitempty"`
+ CountRequests int64 `protobuf:"varint,3,opt,name=countRequests,proto3" json:"countRequests,omitempty"`
+ Bytes int64 `protobuf:"varint,4,opt,name=bytes,proto3" json:"bytes,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopDomainStat) Reset() {
+ *x = ComposeHTTPDNSBoardResponse_TopDomainStat{}
+ mi := &file_service_httpdns_board_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopDomainStat) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ComposeHTTPDNSBoardResponse_TopDomainStat) ProtoMessage() {}
+
+func (x *ComposeHTTPDNSBoardResponse_TopDomainStat) ProtoReflect() protoreflect.Message {
+ mi := &file_service_httpdns_board_proto_msgTypes[5]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ComposeHTTPDNSBoardResponse_TopDomainStat.ProtoReflect.Descriptor instead.
+func (*ComposeHTTPDNSBoardResponse_TopDomainStat) Descriptor() ([]byte, []int) {
+ return file_service_httpdns_board_proto_rawDescGZIP(), []int{1, 3}
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopDomainStat) GetDomainId() int64 {
+ if x != nil {
+ return x.DomainId
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopDomainStat) GetDomainName() string {
+ if x != nil {
+ return x.DomainName
+ }
+ return ""
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopDomainStat) GetCountRequests() int64 {
+ if x != nil {
+ return x.CountRequests
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopDomainStat) GetBytes() int64 {
+ if x != nil {
+ return x.Bytes
+ }
+ return 0
+}
+
+type ComposeHTTPDNSBoardResponse_TopNodeStat struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"`
+ NodeId int64 `protobuf:"varint,2,opt,name=nodeId,proto3" json:"nodeId,omitempty"`
+ NodeName string `protobuf:"bytes,3,opt,name=nodeName,proto3" json:"nodeName,omitempty"`
+ CountRequests int64 `protobuf:"varint,4,opt,name=countRequests,proto3" json:"countRequests,omitempty"`
+ Bytes int64 `protobuf:"varint,5,opt,name=bytes,proto3" json:"bytes,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopNodeStat) Reset() {
+ *x = ComposeHTTPDNSBoardResponse_TopNodeStat{}
+ mi := &file_service_httpdns_board_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopNodeStat) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ComposeHTTPDNSBoardResponse_TopNodeStat) ProtoMessage() {}
+
+func (x *ComposeHTTPDNSBoardResponse_TopNodeStat) ProtoReflect() protoreflect.Message {
+ mi := &file_service_httpdns_board_proto_msgTypes[6]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ComposeHTTPDNSBoardResponse_TopNodeStat.ProtoReflect.Descriptor instead.
+func (*ComposeHTTPDNSBoardResponse_TopNodeStat) Descriptor() ([]byte, []int) {
+ return file_service_httpdns_board_proto_rawDescGZIP(), []int{1, 4}
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopNodeStat) GetClusterId() int64 {
+ if x != nil {
+ return x.ClusterId
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopNodeStat) GetNodeId() int64 {
+ if x != nil {
+ return x.NodeId
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopNodeStat) GetNodeName() string {
+ if x != nil {
+ return x.NodeName
+ }
+ return ""
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopNodeStat) GetCountRequests() int64 {
+ if x != nil {
+ return x.CountRequests
+ }
+ return 0
+}
+
+func (x *ComposeHTTPDNSBoardResponse_TopNodeStat) GetBytes() int64 {
+ if x != nil {
+ return x.Bytes
+ }
+ return 0
+}
+
+var File_service_httpdns_board_proto protoreflect.FileDescriptor
+
+const file_service_httpdns_board_proto_rawDesc = "" +
+ "\n" +
+ "\x1bservice_httpdns_board.proto\x12\x02pb\x1a\x1dmodels/model_node_value.proto\"\x1c\n" +
+ "\x1aComposeHTTPDNSBoardRequest\"\x9c\v\n" +
+ "\x1bComposeHTTPDNSBoardResponse\x12\x1c\n" +
+ "\tcountApps\x18\x01 \x01(\x03R\tcountApps\x12\"\n" +
+ "\fcountDomains\x18\x02 \x01(\x03R\fcountDomains\x12$\n" +
+ "\rcountClusters\x18\x03 \x01(\x03R\rcountClusters\x12\x1e\n" +
+ "\n" +
+ "countNodes\x18\x04 \x01(\x03R\n" +
+ "countNodes\x12,\n" +
+ "\x11countOfflineNodes\x18\x05 \x01(\x03R\x11countOfflineNodes\x12^\n" +
+ "\x11dailyTrafficStats\x18\x1e \x03(\v20.pb.ComposeHTTPDNSBoardResponse.DailyTrafficStatR\x11dailyTrafficStats\x12a\n" +
+ "\x12hourlyTrafficStats\x18\x1f \x03(\v21.pb.ComposeHTTPDNSBoardResponse.HourlyTrafficStatR\x12hourlyTrafficStats\x12L\n" +
+ "\vtopAppStats\x18 \x03(\v2*.pb.ComposeHTTPDNSBoardResponse.TopAppStatR\vtopAppStats\x12U\n" +
+ "\x0etopDomainStats\x18! \x03(\v2-.pb.ComposeHTTPDNSBoardResponse.TopDomainStatR\x0etopDomainStats\x12O\n" +
+ "\ftopNodeStats\x18\" \x03(\v2+.pb.ComposeHTTPDNSBoardResponse.TopNodeStatR\ftopNodeStats\x123\n" +
+ "\rcpuNodeValues\x18# \x03(\v2\r.pb.NodeValueR\rcpuNodeValues\x129\n" +
+ "\x10memoryNodeValues\x18$ \x03(\v2\r.pb.NodeValueR\x10memoryNodeValues\x125\n" +
+ "\x0eloadNodeValues\x18% \x03(\v2\r.pb.NodeValueR\x0eloadNodeValues\x1a`\n" +
+ "\x10DailyTrafficStat\x12\x10\n" +
+ "\x03day\x18\x01 \x01(\tR\x03day\x12\x14\n" +
+ "\x05bytes\x18\x02 \x01(\x03R\x05bytes\x12$\n" +
+ "\rcountRequests\x18\x03 \x01(\x03R\rcountRequests\x1ac\n" +
+ "\x11HourlyTrafficStat\x12\x12\n" +
+ "\x04hour\x18\x01 \x01(\tR\x04hour\x12\x14\n" +
+ "\x05bytes\x18\x02 \x01(\x03R\x05bytes\x12$\n" +
+ "\rcountRequests\x18\x03 \x01(\x03R\rcountRequests\x1ax\n" +
+ "\n" +
+ "TopAppStat\x12\x14\n" +
+ "\x05appId\x18\x01 \x01(\x03R\x05appId\x12\x18\n" +
+ "\aappName\x18\x02 \x01(\tR\aappName\x12$\n" +
+ "\rcountRequests\x18\x03 \x01(\x03R\rcountRequests\x12\x14\n" +
+ "\x05bytes\x18\x04 \x01(\x03R\x05bytes\x1a\x87\x01\n" +
+ "\rTopDomainStat\x12\x1a\n" +
+ "\bdomainId\x18\x01 \x01(\x03R\bdomainId\x12\x1e\n" +
+ "\n" +
+ "domainName\x18\x02 \x01(\tR\n" +
+ "domainName\x12$\n" +
+ "\rcountRequests\x18\x03 \x01(\x03R\rcountRequests\x12\x14\n" +
+ "\x05bytes\x18\x04 \x01(\x03R\x05bytes\x1a\x9b\x01\n" +
+ "\vTopNodeStat\x12\x1c\n" +
+ "\tclusterId\x18\x01 \x01(\x03R\tclusterId\x12\x16\n" +
+ "\x06nodeId\x18\x02 \x01(\x03R\x06nodeId\x12\x1a\n" +
+ "\bnodeName\x18\x03 \x01(\tR\bnodeName\x12$\n" +
+ "\rcountRequests\x18\x04 \x01(\x03R\rcountRequests\x12\x14\n" +
+ "\x05bytes\x18\x05 \x01(\x03R\x05bytes2m\n" +
+ "\x13HTTPDNSBoardService\x12V\n" +
+ "\x13composeHTTPDNSBoard\x12\x1e.pb.ComposeHTTPDNSBoardRequest\x1a\x1f.pb.ComposeHTTPDNSBoardResponseB\x06Z\x04./pbb\x06proto3"
+
+var (
+ file_service_httpdns_board_proto_rawDescOnce sync.Once
+ file_service_httpdns_board_proto_rawDescData []byte
+)
+
+func file_service_httpdns_board_proto_rawDescGZIP() []byte {
+ file_service_httpdns_board_proto_rawDescOnce.Do(func() {
+ file_service_httpdns_board_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_service_httpdns_board_proto_rawDesc), len(file_service_httpdns_board_proto_rawDesc)))
+ })
+ return file_service_httpdns_board_proto_rawDescData
+}
+
+var file_service_httpdns_board_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_service_httpdns_board_proto_goTypes = []any{
+ (*ComposeHTTPDNSBoardRequest)(nil), // 0: pb.ComposeHTTPDNSBoardRequest
+ (*ComposeHTTPDNSBoardResponse)(nil), // 1: pb.ComposeHTTPDNSBoardResponse
+ (*ComposeHTTPDNSBoardResponse_DailyTrafficStat)(nil), // 2: pb.ComposeHTTPDNSBoardResponse.DailyTrafficStat
+ (*ComposeHTTPDNSBoardResponse_HourlyTrafficStat)(nil), // 3: pb.ComposeHTTPDNSBoardResponse.HourlyTrafficStat
+ (*ComposeHTTPDNSBoardResponse_TopAppStat)(nil), // 4: pb.ComposeHTTPDNSBoardResponse.TopAppStat
+ (*ComposeHTTPDNSBoardResponse_TopDomainStat)(nil), // 5: pb.ComposeHTTPDNSBoardResponse.TopDomainStat
+ (*ComposeHTTPDNSBoardResponse_TopNodeStat)(nil), // 6: pb.ComposeHTTPDNSBoardResponse.TopNodeStat
+ (*NodeValue)(nil), // 7: pb.NodeValue
+}
+var file_service_httpdns_board_proto_depIdxs = []int32{
+ 2, // 0: pb.ComposeHTTPDNSBoardResponse.dailyTrafficStats:type_name -> pb.ComposeHTTPDNSBoardResponse.DailyTrafficStat
+ 3, // 1: pb.ComposeHTTPDNSBoardResponse.hourlyTrafficStats:type_name -> pb.ComposeHTTPDNSBoardResponse.HourlyTrafficStat
+ 4, // 2: pb.ComposeHTTPDNSBoardResponse.topAppStats:type_name -> pb.ComposeHTTPDNSBoardResponse.TopAppStat
+ 5, // 3: pb.ComposeHTTPDNSBoardResponse.topDomainStats:type_name -> pb.ComposeHTTPDNSBoardResponse.TopDomainStat
+ 6, // 4: pb.ComposeHTTPDNSBoardResponse.topNodeStats:type_name -> pb.ComposeHTTPDNSBoardResponse.TopNodeStat
+ 7, // 5: pb.ComposeHTTPDNSBoardResponse.cpuNodeValues:type_name -> pb.NodeValue
+ 7, // 6: pb.ComposeHTTPDNSBoardResponse.memoryNodeValues:type_name -> pb.NodeValue
+ 7, // 7: pb.ComposeHTTPDNSBoardResponse.loadNodeValues:type_name -> pb.NodeValue
+ 0, // 8: pb.HTTPDNSBoardService.composeHTTPDNSBoard:input_type -> pb.ComposeHTTPDNSBoardRequest
+ 1, // 9: pb.HTTPDNSBoardService.composeHTTPDNSBoard:output_type -> pb.ComposeHTTPDNSBoardResponse
+ 9, // [9:10] is the sub-list for method output_type
+ 8, // [8:9] is the sub-list for method input_type
+ 8, // [8:8] is the sub-list for extension type_name
+ 8, // [8:8] is the sub-list for extension extendee
+ 0, // [0:8] is the sub-list for field type_name
+}
+
+func init() { file_service_httpdns_board_proto_init() }
+func file_service_httpdns_board_proto_init() {
+ if File_service_httpdns_board_proto != nil {
+ return
+ }
+ file_models_model_node_value_proto_init()
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: unsafe.Slice(unsafe.StringData(file_service_httpdns_board_proto_rawDesc), len(file_service_httpdns_board_proto_rawDesc)),
+ NumEnums: 0,
+ NumMessages: 7,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_service_httpdns_board_proto_goTypes,
+ DependencyIndexes: file_service_httpdns_board_proto_depIdxs,
+ MessageInfos: file_service_httpdns_board_proto_msgTypes,
+ }.Build()
+ File_service_httpdns_board_proto = out.File
+ file_service_httpdns_board_proto_goTypes = nil
+ file_service_httpdns_board_proto_depIdxs = nil
+}
diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_board_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_board_grpc.pb.go
new file mode 100644
index 0000000..8083364
--- /dev/null
+++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_board_grpc.pb.go
@@ -0,0 +1,125 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.6.1
+// - protoc v3.12.4
+// source: service_httpdns_board.proto
+
+package pb
+
+import (
+ context "context"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.64.0 or later.
+const _ = grpc.SupportPackageIsVersion9
+
+const (
+ HTTPDNSBoardService_ComposeHTTPDNSBoard_FullMethodName = "/pb.HTTPDNSBoardService/composeHTTPDNSBoard"
+)
+
+// HTTPDNSBoardServiceClient is the client API for HTTPDNSBoardService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+//
+// HTTPDNS 看板服务
+type HTTPDNSBoardServiceClient interface {
+ // 组合看板数据
+ ComposeHTTPDNSBoard(ctx context.Context, in *ComposeHTTPDNSBoardRequest, opts ...grpc.CallOption) (*ComposeHTTPDNSBoardResponse, error)
+}
+
+type hTTPDNSBoardServiceClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewHTTPDNSBoardServiceClient(cc grpc.ClientConnInterface) HTTPDNSBoardServiceClient {
+ return &hTTPDNSBoardServiceClient{cc}
+}
+
+func (c *hTTPDNSBoardServiceClient) ComposeHTTPDNSBoard(ctx context.Context, in *ComposeHTTPDNSBoardRequest, opts ...grpc.CallOption) (*ComposeHTTPDNSBoardResponse, error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ out := new(ComposeHTTPDNSBoardResponse)
+ err := c.cc.Invoke(ctx, HTTPDNSBoardService_ComposeHTTPDNSBoard_FullMethodName, in, out, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// HTTPDNSBoardServiceServer is the server API for HTTPDNSBoardService service.
+// All implementations should embed UnimplementedHTTPDNSBoardServiceServer
+// for forward compatibility.
+//
+// HTTPDNS 看板服务
+type HTTPDNSBoardServiceServer interface {
+ // 组合看板数据
+ ComposeHTTPDNSBoard(context.Context, *ComposeHTTPDNSBoardRequest) (*ComposeHTTPDNSBoardResponse, error)
+}
+
+// UnimplementedHTTPDNSBoardServiceServer should be embedded to have
+// forward compatible implementations.
+//
+// NOTE: this should be embedded by value instead of pointer to avoid a nil
+// pointer dereference when methods are called.
+type UnimplementedHTTPDNSBoardServiceServer struct{}
+
+func (UnimplementedHTTPDNSBoardServiceServer) ComposeHTTPDNSBoard(context.Context, *ComposeHTTPDNSBoardRequest) (*ComposeHTTPDNSBoardResponse, error) {
+ return nil, status.Error(codes.Unimplemented, "method ComposeHTTPDNSBoard not implemented")
+}
+func (UnimplementedHTTPDNSBoardServiceServer) testEmbeddedByValue() {}
+
+// UnsafeHTTPDNSBoardServiceServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to HTTPDNSBoardServiceServer will
+// result in compilation errors.
+type UnsafeHTTPDNSBoardServiceServer interface {
+ mustEmbedUnimplementedHTTPDNSBoardServiceServer()
+}
+
+func RegisterHTTPDNSBoardServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSBoardServiceServer) {
+ // If the following call panics, it indicates UnimplementedHTTPDNSBoardServiceServer was
+ // embedded by pointer and is nil. This will cause panics if an
+ // unimplemented method is ever invoked, so we test this at initialization
+ // time to prevent it from happening at runtime later due to I/O.
+ if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
+ t.testEmbeddedByValue()
+ }
+ s.RegisterService(&HTTPDNSBoardService_ServiceDesc, srv)
+}
+
+func _HTTPDNSBoardService_ComposeHTTPDNSBoard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ComposeHTTPDNSBoardRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(HTTPDNSBoardServiceServer).ComposeHTTPDNSBoard(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: HTTPDNSBoardService_ComposeHTTPDNSBoard_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(HTTPDNSBoardServiceServer).ComposeHTTPDNSBoard(ctx, req.(*ComposeHTTPDNSBoardRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+// HTTPDNSBoardService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSBoardService service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var HTTPDNSBoardService_ServiceDesc = grpc.ServiceDesc{
+ ServiceName: "pb.HTTPDNSBoardService",
+ HandlerType: (*HTTPDNSBoardServiceServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "composeHTTPDNSBoard",
+ Handler: _HTTPDNSBoardService_ComposeHTTPDNSBoard_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "service_httpdns_board.proto",
+}
diff --git a/EdgeCommon/pkg/serverconfigs/http_auth_method_base.go b/EdgeCommon/pkg/serverconfigs/http_auth_method_base.go
index 1d3dc0a..c85f4cd 100644
--- a/EdgeCommon/pkg/serverconfigs/http_auth_method_base.go
+++ b/EdgeCommon/pkg/serverconfigs/http_auth_method_base.go
@@ -12,6 +12,7 @@ import (
)
var httpAuthTimestampRegexp = regexp.MustCompile(`^\d{10}$`)
+var httpAuthHexTimestampRegexp = regexp.MustCompile(`^[0-9a-fA-F]{1,16}$`)
type HTTPAuthBaseMethod struct {
Exts []string `json:"exts"`
diff --git a/EdgeCommon/pkg/serverconfigs/http_auth_methods_plus.go b/EdgeCommon/pkg/serverconfigs/http_auth_methods_plus.go
index f63b541..1b61694 100644
--- a/EdgeCommon/pkg/serverconfigs/http_auth_methods_plus.go
+++ b/EdgeCommon/pkg/serverconfigs/http_auth_methods_plus.go
@@ -7,12 +7,12 @@ type HTTPAuthType = string
const (
HTTPAuthTypeBasicAuth HTTPAuthType = "basicAuth" // BasicAuth
- HTTPAuthTypeSubRequest HTTPAuthType = "subRequest" // 子请求
-
- HTTPAuthTypeTypeA HTTPAuthType = "typeA"
- HTTPAuthTypeTypeB HTTPAuthType = "typeB"
- HTTPAuthTypeTypeC HTTPAuthType = "typeC"
- HTTPAuthTypeTypeD HTTPAuthType = "typeD"
+ HTTPAuthTypeSubRequest HTTPAuthType = "subRequest" // SubRequest
+ HTTPAuthTypeTypeA HTTPAuthType = "typeA"
+ HTTPAuthTypeTypeB HTTPAuthType = "typeB"
+ HTTPAuthTypeTypeC HTTPAuthType = "typeC"
+ HTTPAuthTypeTypeD HTTPAuthType = "typeD"
+ HTTPAuthTypeTypeE HTTPAuthType = "typeE"
)
type HTTPAuthTypeDefinition struct {
@@ -23,10 +23,11 @@ type HTTPAuthTypeDefinition struct {
}
func FindAllHTTPAuthTypes(role string) []*HTTPAuthTypeDefinition {
- var urlDocA = ""
- var urlDocB = ""
- var urlDocC = ""
- var urlDocD = ""
+ urlDocA := ""
+ urlDocB := ""
+ urlDocC := ""
+ urlDocD := ""
+ urlDocE := "https://help.aliyun.com/zh/cdn/user-guide/type-c-signing"
switch role {
case "admin":
@@ -66,15 +67,21 @@ func FindAllHTTPAuthTypes(role string) []*HTTPAuthTypeDefinition {
Description: "示例URL:https://example.com/images/test.jpg?sign=f66af42f87cf63a64f4b86ec11c7797a&t=1661753717
[算法详解]",
IsPlus: true,
},
+ {
+ Name: "URL鉴权E",
+ Code: HTTPAuthTypeTypeE,
+ Description: "严格兼容阿里云 Type-C 路径鉴权,示例URL:https://example.com/3a2c79f2d2f0df2f8f9e05ec9f482e5d/67cfdb9e/images/test.jpg
[阿里云文档]",
+ IsPlus: true,
+ },
{
Name: "基本认证",
Code: HTTPAuthTypeBasicAuth,
- Description: "BasicAuth,最简单的HTTP请求认证方式,通过传递Authorization: Basic xxx Header认证。",
+ Description: "BasicAuth,最简单的 HTTP 请求认证方式,通过传递 Authorization: Basic xxx Header 认证。",
},
{
Name: "子请求",
Code: HTTPAuthTypeSubRequest,
- Description: "通过自定义的URL子请求来认证请求。",
+ Description: "通过自定义的 URL 子请求来认证请求。",
},
}
}
diff --git a/EdgeCommon/pkg/serverconfigs/http_auth_policy_init_plus.go b/EdgeCommon/pkg/serverconfigs/http_auth_policy_init_plus.go
index 2b45ca5..084554a 100644
--- a/EdgeCommon/pkg/serverconfigs/http_auth_policy_init_plus.go
+++ b/EdgeCommon/pkg/serverconfigs/http_auth_policy_init_plus.go
@@ -22,6 +22,8 @@ func (this *HTTPAuthPolicy) Init() error {
this.method = NewHTTPAuthTypeCMethod()
case HTTPAuthTypeTypeD:
this.method = NewHTTPAuthTypeDMethod()
+ case HTTPAuthTypeTypeE:
+ this.method = NewHTTPAuthTypeEMethod()
}
if this.method == nil {
diff --git a/EdgeDNS/build/build.sh b/EdgeDNS/build/build.sh
index 6da3934..28d6cad 100644
--- a/EdgeDNS/build/build.sh
+++ b/EdgeDNS/build/build.sh
@@ -1,5 +1,138 @@
#!/usr/bin/env bash
+function find-binary() {
+ local candidate
+ for candidate in "$@"; do
+ if [ -z "$candidate" ]; then
+ continue
+ fi
+ if [ -x "$candidate" ]; then
+ echo "$candidate"
+ return 0
+ fi
+ if command -v "$candidate" >/dev/null 2>&1; then
+ command -v "$candidate"
+ return 0
+ fi
+ done
+ return 1
+}
+
+function host-goarch() {
+ case "$(uname -m)" in
+ x86_64|amd64)
+ echo "amd64"
+ ;;
+ aarch64|arm64)
+ echo "arm64"
+ ;;
+ i386|i486|i586|i686)
+ echo "386"
+ ;;
+ mips64)
+ echo "mips64"
+ ;;
+ mips64el)
+ echo "mips64le"
+ ;;
+ *)
+ echo ""
+ ;;
+ esac
+}
+
+function find-linux-static-toolchain() {
+ local arch=$1
+ local cc_bin=""
+ local cxx_bin=""
+ local host_arch
+
+ host_arch=$(host-goarch)
+
+ case "$arch" in
+ amd64)
+ cc_bin=$(find-binary \
+ "/usr/local/gcc/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-gcc" \
+ "/usr/local/opt/musl-cross/bin/x86_64-linux-musl-gcc" \
+ "x86_64-unknown-linux-gnu-gcc" \
+ "x86_64-linux-musl-gcc" \
+ "musl-gcc")
+ cxx_bin=$(find-binary \
+ "/usr/local/gcc/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-g++" \
+ "/usr/local/opt/musl-cross/bin/x86_64-linux-musl-g++" \
+ "x86_64-unknown-linux-gnu-g++" \
+ "x86_64-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "amd64" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "amd64" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ 386)
+ cc_bin=$(find-binary "/usr/local/opt/musl-cross/bin/i486-linux-musl-gcc" "i486-linux-musl-gcc")
+ cxx_bin=$(find-binary "/usr/local/opt/musl-cross/bin/i486-linux-musl-g++" "i486-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "386" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "386" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ arm64)
+ cc_bin=$(find-binary \
+ "/usr/local/gcc/aarch64-unknown-linux-gnu/bin/aarch64-unknown-linux-gnu-gcc" \
+ "/usr/local/opt/musl-cross/bin/aarch64-linux-musl-gcc" \
+ "aarch64-unknown-linux-gnu-gcc" \
+ "aarch64-linux-musl-gcc")
+ cxx_bin=$(find-binary \
+ "/usr/local/gcc/aarch64-unknown-linux-gnu/bin/aarch64-unknown-linux-gnu-g++" \
+ "/usr/local/opt/musl-cross/bin/aarch64-linux-musl-g++" \
+ "aarch64-unknown-linux-gnu-g++" \
+ "aarch64-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "arm64" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "arm64" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ mips64)
+ cc_bin=$(find-binary "/usr/local/opt/musl-cross/bin/mips64-linux-musl-gcc" "mips64-linux-musl-gcc")
+ cxx_bin=$(find-binary "/usr/local/opt/musl-cross/bin/mips64-linux-musl-g++" "mips64-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "mips64" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "mips64" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ mips64le)
+ cc_bin=$(find-binary "/usr/local/opt/musl-cross/bin/mips64el-linux-musl-gcc" "mips64el-linux-musl-gcc")
+ cxx_bin=$(find-binary "/usr/local/opt/musl-cross/bin/mips64el-linux-musl-g++" "mips64el-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "mips64le" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "mips64le" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+
+ if [ -z "$cc_bin" ]; then
+ return 1
+ fi
+ if [ -z "$cxx_bin" ]; then
+ cxx_bin="$cc_bin"
+ fi
+
+ echo "$cc_bin|$cxx_bin"
+ return 0
+}
+
function build() {
ROOT=$(dirname "$0")
NAME="edge-dns"
@@ -18,10 +151,9 @@ function build() {
fi
echo "checking ..."
- ZIP_PATH=$(which zip)
- if [ -z "$ZIP_PATH" ]; then
+ if ! command -v zip >/dev/null 2>&1; then
echo "we need 'zip' command to compress files"
- exit
+ exit 1
fi
echo "building v${VERSION}/${OS}/${ARCH} ..."
@@ -37,38 +169,20 @@ function build() {
fi
cp "$ROOT"/configs/api_dns.template.yaml "$DIST"/configs
- copy_fluent_bit_assets "$ROOT" "$DIST" "$OS" "$ARCH" || exit 1
echo "building ..."
- MUSL_DIR="/usr/local/opt/musl-cross/bin"
- CC_PATH=""
- CXX_PATH=""
- if [[ $(uname -a) == *"Darwin"* && "${OS}" == "linux" ]]; then
- # /usr/local/opt/musl-cross/bin/
- if [ "${ARCH}" == "amd64" ]; then
- CC_PATH="x86_64-linux-musl-gcc"
- CXX_PATH="x86_64-linux-musl-g++"
+ if [ "$OS" == "linux" ]; then
+ TOOLCHAIN=$(find-linux-static-toolchain "$ARCH")
+ if [ -z "$TOOLCHAIN" ]; then
+ echo "could not find a static Linux toolchain for ${ARCH}"
+ echo "install a musl toolchain before building edge-dns"
+ exit 1
fi
- if [ "${ARCH}" == "386" ]; then
- CC_PATH="i486-linux-musl-gcc"
- CXX_PATH="i486-linux-musl-g++"
- fi
- if [ "${ARCH}" == "arm64" ]; then
- CC_PATH="aarch64-linux-musl-gcc"
- CXX_PATH="aarch64-linux-musl-g++"
- fi
- if [ "${ARCH}" == "mips64" ]; then
- CC_PATH="mips64-linux-musl-gcc"
- CXX_PATH="mips64-linux-musl-g++"
- fi
- if [ "${ARCH}" == "mips64le" ]; then
- CC_PATH="mips64el-linux-musl-gcc"
- CXX_PATH="mips64el-linux-musl-g++"
- fi
- fi
- if [ ! -z $CC_PATH ]; then
- env CC=$MUSL_DIR/$CC_PATH CXX=$MUSL_DIR/$CXX_PATH GOOS="${OS}" GOARCH="${ARCH}" CGO_ENABLED=1 go build -trimpath -tags="plus" -o "$DIST"/bin/${NAME} -ldflags "-linkmode external -extldflags -static -s -w" "$ROOT"/../cmd/edge-dns/main.go
+
+ CC_BIN=${TOOLCHAIN%|*}
+ CXX_BIN=${TOOLCHAIN#*|}
+ env CC="$CC_BIN" CXX="$CXX_BIN" GOOS="${OS}" GOARCH="${ARCH}" CGO_ENABLED=1 go build -trimpath -tags="plus" -o "$DIST"/bin/${NAME} -ldflags "-linkmode external -extldflags -static -s -w" "$ROOT"/../cmd/edge-dns/main.go
else
env GOOS="${OS}" GOARCH="${ARCH}" CGO_ENABLED=1 go build -trimpath -tags="plus" -o "$DIST"/bin/${NAME} -ldflags="-s -w" "$ROOT"/../cmd/edge-dns/main.go
fi
@@ -76,7 +190,7 @@ function build() {
# check build result
RESULT=$?
if [ "${RESULT}" != "0" ]; then
- exit
+ exit 1
fi
# delete hidden files
@@ -95,81 +209,6 @@ function build() {
echo "OK"
}
-function copy_fluent_bit_assets() {
- ROOT=$1
- DIST=$2
- OS=$3
- ARCH=$4
- FLUENT_ROOT="$ROOT/../../deploy/fluent-bit"
- FLUENT_DIST="$DIST/deploy/fluent-bit"
-
- if [ ! -d "$FLUENT_ROOT" ]; then
- echo "[error] fluent-bit source directory not found: $FLUENT_ROOT"
- return 1
- fi
- verify_fluent_bit_package_matrix "$FLUENT_ROOT" "$ARCH" || return 1
-
- rm -rf "$FLUENT_DIST"
- mkdir -p "$FLUENT_DIST"
-
- for file in fluent-bit.conf fluent-bit-dns.conf fluent-bit-https.conf fluent-bit-dns-https.conf fluent-bit-windows.conf fluent-bit-windows-https.conf parsers.conf clickhouse-upstream.conf clickhouse-upstream-windows.conf README.md; do
- if [ -f "$FLUENT_ROOT/$file" ]; then
- cp "$FLUENT_ROOT/$file" "$FLUENT_DIST/"
- fi
- done
-
- if [ "$OS" = "linux" ]; then
- PACKAGE_SRC="$FLUENT_ROOT/packages/linux-$ARCH"
- PACKAGE_DST="$FLUENT_DIST/packages/linux-$ARCH"
- if [ -d "$PACKAGE_SRC" ]; then
- mkdir -p "$PACKAGE_DST"
- cp -R "$PACKAGE_SRC/." "$PACKAGE_DST/"
- else
- echo "[error] fluent-bit package directory not found: $PACKAGE_SRC"
- return 1
- fi
- fi
-
- rm -f "$FLUENT_DIST/.gitignore"
- rm -f "$FLUENT_DIST"/logs.db*
- rm -rf "$FLUENT_DIST/storage"
-
- return 0
-}
-
-function verify_fluent_bit_package_matrix() {
- FLUENT_ROOT=$1
- ARCH=$2
- REQUIRED_FILES=()
- if [ "$ARCH" = "amd64" ]; then
- REQUIRED_FILES=(
- "packages/linux-amd64/fluent-bit_4.2.2_amd64.deb"
- "packages/linux-amd64/fluent-bit-4.2.2-1.x86_64.rpm"
- )
- elif [ "$ARCH" = "arm64" ]; then
- REQUIRED_FILES=(
- "packages/linux-arm64/fluent-bit_4.2.2_arm64.deb"
- "packages/linux-arm64/fluent-bit-4.2.2-1.aarch64.rpm"
- )
- else
- echo "[error] unsupported arch for fluent-bit package validation: $ARCH"
- return 1
- fi
-
- MISSING=0
- for FILE in "${REQUIRED_FILES[@]}"; do
- if [ ! -f "$FLUENT_ROOT/$FILE" ]; then
- echo "[error] fluent-bit matrix package missing: $FLUENT_ROOT/$FILE"
- MISSING=1
- fi
- done
-
- if [ "$MISSING" -ne 0 ]; then
- return 1
- fi
- return 0
-}
-
function lookup-version() {
FILE=$1
VERSION_DATA=$(cat "$FILE")
@@ -179,7 +218,7 @@ function lookup-version() {
echo "$VERSION"
else
echo "could not match version"
- exit
+ exit 1
fi
}
diff --git a/EdgeDNS/internal/const/const.go b/EdgeDNS/internal/const/const.go
index 1770316..3d8175a 100644
--- a/EdgeDNS/internal/const/const.go
+++ b/EdgeDNS/internal/const/const.go
@@ -1,7 +1,7 @@
package teaconst
const (
- Version = "1.4.9" //1.3.8.2
+ Version = "1.5.0" //1.3.8.2
ProductName = "Edge DNS"
ProcessName = "edge-dns"
diff --git a/EdgeHttpDNS/build/build.sh b/EdgeHttpDNS/build/build.sh
index adc3efb..889b702 100644
--- a/EdgeHttpDNS/build/build.sh
+++ b/EdgeHttpDNS/build/build.sh
@@ -34,10 +34,14 @@ function build() {
mkdir -p "$DIST"/data
cp "$ROOT"/configs/api_httpdns.template.yaml "$DIST"/configs
- copy_fluent_bit_assets "$ROOT" "$DIST" "$OS" "$ARCH" || exit 1
- env GOOS="${OS}" GOARCH="${ARCH}" CGO_ENABLED=1 \
- go build -trimpath -o "$DIST"/bin/${NAME} -ldflags="-s -w" "$ROOT"/../cmd/edge-httpdns/main.go
+ if [ "${OS}" = "linux" ]; then
+ env GOOS="${OS}" GOARCH="${ARCH}" CGO_ENABLED=0 \
+ go build -trimpath -o "$DIST"/bin/${NAME} -ldflags="-s -w" "$ROOT"/../cmd/edge-httpdns/main.go
+ else
+ env GOOS="${OS}" GOARCH="${ARCH}" CGO_ENABLED=1 \
+ go build -trimpath -o "$DIST"/bin/${NAME} -ldflags="-s -w" "$ROOT"/../cmd/edge-httpdns/main.go
+ fi
if [ ! -f "$DIST"/bin/${NAME} ]; then
echo "build failed!"
@@ -60,81 +64,6 @@ function build() {
echo "OK"
}
-function copy_fluent_bit_assets() {
- ROOT=$1
- DIST=$2
- OS=$3
- ARCH=$4
- FLUENT_ROOT="$ROOT/../../deploy/fluent-bit"
- FLUENT_DIST="$DIST/deploy/fluent-bit"
-
- if [ ! -d "$FLUENT_ROOT" ]; then
- echo "[error] fluent-bit source directory not found: $FLUENT_ROOT"
- return 1
- fi
- verify_fluent_bit_package_matrix "$FLUENT_ROOT" "$ARCH" || return 1
-
- rm -rf "$FLUENT_DIST"
- mkdir -p "$FLUENT_DIST"
-
- for file in fluent-bit.conf fluent-bit-dns.conf fluent-bit-https.conf fluent-bit-dns-https.conf fluent-bit-windows.conf fluent-bit-windows-https.conf parsers.conf clickhouse-upstream.conf clickhouse-upstream-windows.conf README.md; do
- if [ -f "$FLUENT_ROOT/$file" ]; then
- cp "$FLUENT_ROOT/$file" "$FLUENT_DIST/"
- fi
- done
-
- if [ "$OS" = "linux" ]; then
- PACKAGE_SRC="$FLUENT_ROOT/packages/linux-$ARCH"
- PACKAGE_DST="$FLUENT_DIST/packages/linux-$ARCH"
- if [ -d "$PACKAGE_SRC" ]; then
- mkdir -p "$PACKAGE_DST"
- cp -R "$PACKAGE_SRC/." "$PACKAGE_DST/"
- else
- echo "[error] fluent-bit package directory not found: $PACKAGE_SRC"
- return 1
- fi
- fi
-
- rm -f "$FLUENT_DIST/.gitignore"
- rm -f "$FLUENT_DIST"/logs.db*
- rm -rf "$FLUENT_DIST/storage"
-
- return 0
-}
-
-function verify_fluent_bit_package_matrix() {
- FLUENT_ROOT=$1
- ARCH=$2
- REQUIRED_FILES=()
- if [ "$ARCH" = "amd64" ]; then
- REQUIRED_FILES=(
- "packages/linux-amd64/fluent-bit_4.2.2_amd64.deb"
- "packages/linux-amd64/fluent-bit-4.2.2-1.x86_64.rpm"
- )
- elif [ "$ARCH" = "arm64" ]; then
- REQUIRED_FILES=(
- "packages/linux-arm64/fluent-bit_4.2.2_arm64.deb"
- "packages/linux-arm64/fluent-bit-4.2.2-1.aarch64.rpm"
- )
- else
- echo "[error] unsupported arch for fluent-bit package validation: $ARCH"
- return 1
- fi
-
- MISSING=0
- for FILE in "${REQUIRED_FILES[@]}"; do
- if [ ! -f "$FLUENT_ROOT/$FILE" ]; then
- echo "[error] fluent-bit matrix package missing: $FLUENT_ROOT/$FILE"
- MISSING=1
- fi
- done
-
- if [ "$MISSING" -ne 0 ]; then
- return 1
- fi
- return 0
-}
-
function lookup-version() {
FILE=$1
VERSION_DATA=$(cat "$FILE")
diff --git a/EdgeHttpDNS/go.mod b/EdgeHttpDNS/go.mod
index fec8371..7d7f412 100644
--- a/EdgeHttpDNS/go.mod
+++ b/EdgeHttpDNS/go.mod
@@ -8,21 +8,29 @@ require (
github.com/TeaOSLab/EdgeCommon v0.0.0-00010101000000-000000000000
github.com/iwind/TeaGo v0.0.0-20240411075713-6c1fc9aca7b6
github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4
+ github.com/miekg/dns v1.1.72
+ github.com/shirou/gopsutil/v3 v3.24.5
+ golang.org/x/sys v0.39.0
google.golang.org/grpc v1.78.0
+ gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
)
require (
- github.com/miekg/dns v1.1.72 // indirect
+ github.com/go-ole/go-ole v1.2.6 // indirect
+ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/oschwald/geoip2-golang v1.13.0 // indirect
github.com/oschwald/maxminddb-golang v1.13.0 // indirect
+ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
+ github.com/shoenig/go-m1cpu v0.1.6 // indirect
+ github.com/tklauser/go-sysconf v0.3.13 // indirect
+ github.com/tklauser/numcpus v0.7.0 // indirect
+ github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/mod v0.31.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sync v0.19.0 // indirect
- golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/tools v0.40.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
google.golang.org/protobuf v1.36.10 // indirect
- gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
)
diff --git a/EdgeHttpDNS/go.sum b/EdgeHttpDNS/go.sum
index fe5cf68..b43bee8 100644
--- a/EdgeHttpDNS/go.sum
+++ b/EdgeHttpDNS/go.sum
@@ -1,9 +1,14 @@
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+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/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -16,12 +21,32 @@ github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+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/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
github.com/oschwald/geoip2-golang v1.13.0 h1:Q44/Ldc703pasJeP5V9+aFSZFmBN7DKHbNsSFzQATJI=
github.com/oschwald/geoip2-golang v1.13.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
github.com/oschwald/maxminddb-golang v1.13.0 h1:R8xBorY71s84yO06NgTmQvqvTvlS/bnYZrrWX1MElnU=
github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
+github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
+github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
+github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
+github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
+github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
+github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
+github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
+github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
@@ -36,22 +61,19 @@ go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJr
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
-golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
-golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
-golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
-golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
-golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
-golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
diff --git a/EdgeHttpDNS/internal/const/const.go b/EdgeHttpDNS/internal/const/const.go
index f254982..46cf142 100644
--- a/EdgeHttpDNS/internal/const/const.go
+++ b/EdgeHttpDNS/internal/const/const.go
@@ -1,7 +1,7 @@
package teaconst
const (
- Version = "1.4.9"
+ Version = "1.5.0"
ProductName = "Edge HTTPDNS"
ProcessName = "edge-httpdns"
diff --git a/EdgeHttpDNS/internal/nodes/status_manager.go b/EdgeHttpDNS/internal/nodes/status_manager.go
index 2a3c159..3f487f3 100644
--- a/EdgeHttpDNS/internal/nodes/status_manager.go
+++ b/EdgeHttpDNS/internal/nodes/status_manager.go
@@ -15,18 +15,28 @@ import (
teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const"
"github.com/TeaOSLab/EdgeHttpDNS/internal/rpc"
"github.com/TeaOSLab/EdgeHttpDNS/internal/utils"
+ "github.com/iwind/TeaGo/maps"
+ "github.com/shirou/gopsutil/v3/cpu"
+ "github.com/shirou/gopsutil/v3/mem"
)
-
type StatusManager struct {
quitCh <-chan struct{}
ticker *time.Ticker
+
+ isFirstTime bool
+ cpuUpdatedTime time.Time
+ cpuLogicalCount int
+ cpuPhysicalCount int
}
func NewStatusManager(quitCh <-chan struct{}) *StatusManager {
return &StatusManager{
- quitCh: quitCh,
- ticker: time.NewTicker(30 * time.Second),
+ quitCh: quitCh,
+ ticker: time.NewTicker(30 * time.Second),
+ isFirstTime: true,
+ cpuUpdatedTime: time.Now(),
+ cpuLogicalCount: runtime.NumCPU(),
}
}
@@ -72,10 +82,12 @@ func (m *StatusManager) update() {
IsActive: true,
StatusJSON: statusJSON,
})
-
if err != nil {
log.Println("[HTTPDNS_NODE][status]update status failed:", err.Error())
}
+
+ m.reportNodeValues(rpcClient, status)
+ m.isFirstTime = false
}
func (m *StatusManager) collectStatus() *nodeconfigs.NodeStatus {
@@ -87,8 +99,8 @@ func (m *StatusManager) collectStatus() *nodeconfigs.NodeStatus {
ConfigVersion: 0,
OS: runtime.GOOS,
Arch: runtime.GOARCH,
- CPULogicalCount: runtime.NumCPU(),
- CPUPhysicalCount: runtime.NumCPU(),
+ CPULogicalCount: m.cpuLogicalCount,
+ CPUPhysicalCount: m.cpuPhysicalCount,
IsActive: true,
ConnectionCount: 0,
UpdatedAt: now,
@@ -104,26 +116,104 @@ func (m *StatusManager) collectStatus() *nodeconfigs.NodeStatus {
}
}
-
hostname, _ := os.Hostname()
status.Hostname = hostname
exePath, _ := os.Executable()
status.ExePath = exePath
- var memStats runtime.MemStats
- runtime.ReadMemStats(&memStats)
- status.MemoryTotal = memStats.Sys
- if status.MemoryTotal > 0 {
- status.MemoryUsage = float64(memStats.Alloc) / float64(status.MemoryTotal)
+ m.updateCPU(status)
+ m.updateMemory(status)
+ m.updateLoad(status)
+
+ return status
+}
+
+func (m *StatusManager) updateCPU(status *nodeconfigs.NodeStatus) {
+ duration := time.Duration(0)
+ if m.isFirstTime {
+ duration = 100 * time.Millisecond
}
+ percents, err := cpu.Percent(duration, false)
+ if err == nil && len(percents) > 0 {
+ status.CPUUsage = percents[0] / 100
+ }
+
+ if time.Since(m.cpuUpdatedTime) >= 5*time.Minute || m.cpuLogicalCount <= 0 {
+ m.cpuUpdatedTime = time.Now()
+
+ if logicalCount, countErr := cpu.Counts(true); countErr == nil && logicalCount > 0 {
+ m.cpuLogicalCount = logicalCount
+ }
+ if physicalCount, countErr := cpu.Counts(false); countErr == nil && physicalCount > 0 {
+ m.cpuPhysicalCount = physicalCount
+ }
+ }
+
+ status.CPULogicalCount = m.cpuLogicalCount
+ if m.cpuPhysicalCount > 0 {
+ status.CPUPhysicalCount = m.cpuPhysicalCount
+ }
+}
+
+func (m *StatusManager) updateMemory(status *nodeconfigs.NodeStatus) {
+ stat, err := mem.VirtualMemory()
+ if err != nil || stat == nil || stat.Total == 0 {
+ return
+ }
+
+ usedBytes := stat.Used
+ if stat.Total > stat.Free+stat.Buffers+stat.Cached {
+ usedBytes = stat.Total - stat.Free - stat.Buffers - stat.Cached
+ }
+
+ status.MemoryTotal = stat.Total
+ status.MemoryUsage = float64(usedBytes) / float64(stat.Total)
+}
+
+func (m *StatusManager) updateLoad(status *nodeconfigs.NodeStatus) {
load1m, load5m, load15m := readLoadAvg()
status.Load1m = load1m
status.Load5m = load5m
status.Load15m = load15m
+}
- return status
+func (m *StatusManager) reportNodeValues(rpcClient *rpc.RPCClient, status *nodeconfigs.NodeStatus) {
+ if rpcClient == nil || status == nil {
+ return
+ }
+
+ m.createNodeValue(rpcClient, nodeconfigs.NodeValueItemCPU, maps.Map{
+ "usage": status.CPUUsage,
+ "cores": status.CPULogicalCount,
+ })
+ m.createNodeValue(rpcClient, nodeconfigs.NodeValueItemMemory, maps.Map{
+ "usage": status.MemoryUsage,
+ "total": status.MemoryTotal,
+ })
+ m.createNodeValue(rpcClient, nodeconfigs.NodeValueItemLoad, maps.Map{
+ "load1m": status.Load1m,
+ "load5m": status.Load5m,
+ "load15m": status.Load15m,
+ })
+}
+
+func (m *StatusManager) createNodeValue(rpcClient *rpc.RPCClient, item string, value maps.Map) {
+ valueJSON, err := json.Marshal(value)
+ if err != nil {
+ log.Println("[HTTPDNS_NODE][status]marshal node value failed:", err.Error())
+ return
+ }
+
+ _, err = rpcClient.NodeValueRPC.CreateNodeValue(rpcClient.Context(), &pb.CreateNodeValueRequest{
+ Item: item,
+ ValueJSON: valueJSON,
+ CreatedAt: time.Now().Unix(),
+ })
+ if err != nil {
+ log.Println("[HTTPDNS_NODE][status]create node value failed:", item, err.Error())
+ }
}
func readLoadAvg() (float64, float64, float64) {
diff --git a/EdgeHttpDNS/internal/rpc/rpc_client.go b/EdgeHttpDNS/internal/rpc/rpc_client.go
index 52d76c1..3fdcd40 100644
--- a/EdgeHttpDNS/internal/rpc/rpc_client.go
+++ b/EdgeHttpDNS/internal/rpc/rpc_client.go
@@ -26,13 +26,13 @@ import (
"sync/atomic"
)
-
type RPCClient struct {
apiConfig *configs.APIConfig
conns []*grpc.ClientConn
locker sync.RWMutex
NodeTaskRPC pb.NodeTaskServiceClient
+ NodeValueRPC pb.NodeValueServiceClient
HTTPDNSNodeRPC pb.HTTPDNSNodeServiceClient
HTTPDNSClusterRPC pb.HTTPDNSClusterServiceClient
HTTPDNSAppRPC pb.HTTPDNSAppServiceClient
@@ -47,7 +47,6 @@ type RPCClient struct {
totalCostMs int64
}
-
func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
if apiConfig == nil {
return nil, errors.New("api config should not be nil")
@@ -55,6 +54,7 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
client := &RPCClient{apiConfig: apiConfig}
client.NodeTaskRPC = pb.NewNodeTaskServiceClient(client)
+ client.NodeValueRPC = pb.NewNodeValueServiceClient(client)
client.HTTPDNSNodeRPC = pb.NewHTTPDNSNodeServiceClient(client)
client.HTTPDNSClusterRPC = pb.NewHTTPDNSClusterServiceClient(client)
client.HTTPDNSAppRPC = pb.NewHTTPDNSAppServiceClient(client)
@@ -212,7 +212,6 @@ func (c *RPCClient) GetAndResetMetrics() (total int64, failed int64, avgCostSeco
return
}
-
func (c *RPCClient) NewStream(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) {
conn := c.pickConn()
if conn == nil {
diff --git a/EdgeNode/.gitignore b/EdgeNode/.gitignore
index e3ed1cd..877a92d 100644
--- a/EdgeNode/.gitignore
+++ b/EdgeNode/.gitignore
@@ -8,6 +8,8 @@ configs/api_node.yaml
# Build binaries
bin/
+libs/
+.third_party_build/
# Runtime Data
data/
diff --git a/EdgeNode/build/build-libs-ubuntu2204.sh b/EdgeNode/build/build-libs-ubuntu2204.sh
new file mode 100755
index 0000000..35b0b1f
--- /dev/null
+++ b/EdgeNode/build/build-libs-ubuntu2204.sh
@@ -0,0 +1,178 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+function host-goarch() {
+ case "$(uname -m)" in
+ x86_64|amd64)
+ echo "amd64"
+ ;;
+ aarch64|arm64)
+ echo "arm64"
+ ;;
+ *)
+ echo ""
+ ;;
+ esac
+}
+
+function require-command() {
+ local command_name=$1
+ if ! command -v "$command_name" >/dev/null 2>&1; then
+ echo "missing required command: $command_name"
+ return 1
+ fi
+}
+
+function cpu_count() {
+ if command -v nproc >/dev/null 2>&1; then
+ nproc
+ else
+ getconf _NPROCESSORS_ONLN
+ fi
+}
+
+function download() {
+ local url=$1
+ local output=$2
+ if [ ! -f "$output" ]; then
+ curl -fsSL "$url" -o "$output"
+ fi
+}
+
+function prepare-dir() {
+ local dir=$1
+ rm -rf "$dir"
+ mkdir -p "$dir"
+}
+
+function copy-tree() {
+ local from_dir=$1
+ local to_dir=$2
+ rm -rf "$to_dir"
+ mkdir -p "$to_dir"
+ cp -a "$from_dir"/. "$to_dir"/
+}
+
+function copy-static-lib() {
+ local pattern=$1
+ local destination=$2
+ local source_path=""
+
+ source_path=$(find "$(dirname "$pattern")" -type f -name "$(basename "$pattern")" | head -n 1)
+ if [ -z "$source_path" ]; then
+ echo "missing static library: $pattern"
+ return 1
+ fi
+
+ cp "$source_path" "$destination"
+}
+
+ROOT=$(cd "$(dirname "$0")/.." && pwd)
+ARCH=${1:-$(host-goarch)}
+HOST_ARCH=$(host-goarch)
+LIBPCAP_VERSION=${LIBPCAP_VERSION:-1.10.5}
+BROTLI_VERSION=${BROTLI_VERSION:-1.1.0}
+WORKDIR=${WORKDIR:-"$ROOT/.third_party_build"}
+DOWNLOAD_DIR="$WORKDIR/downloads"
+SOURCE_DIR="$WORKDIR/sources"
+BUILD_DIR="$WORKDIR/build"
+LIBPCAP_URL="https://www.tcpdump.org/release/libpcap-${LIBPCAP_VERSION}.tar.gz"
+BROTLI_URL="https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz"
+
+if [ -z "$ARCH" ]; then
+ echo "unsupported host architecture: $(uname -m)"
+ echo "usage: $0 [amd64|arm64]"
+ exit 1
+fi
+
+if [ "$ARCH" != "amd64" ] && [ "$ARCH" != "arm64" ]; then
+ echo "unsupported architecture: $ARCH"
+ echo "supported architectures: amd64 arm64"
+ exit 1
+fi
+
+if [ -n "$HOST_ARCH" ] && [ "$ARCH" != "$HOST_ARCH" ]; then
+ echo "this helper only builds native Ubuntu 22.04 static libraries"
+ echo "host arch: ${HOST_ARCH}, requested arch: ${ARCH}"
+ exit 1
+fi
+
+for tool in curl tar make cmake gcc g++ ar ranlib; do
+ require-command "$tool"
+done
+
+mkdir -p "$DOWNLOAD_DIR" "$SOURCE_DIR" "$BUILD_DIR"
+
+echo "building third-party static libraries for ${ARCH} ..."
+echo "workspace: $WORKDIR"
+
+LIBPCAP_ARCHIVE="$DOWNLOAD_DIR/libpcap-${LIBPCAP_VERSION}.tar.gz"
+BROTLI_ARCHIVE="$DOWNLOAD_DIR/brotli-${BROTLI_VERSION}.tar.gz"
+
+download "$LIBPCAP_URL" "$LIBPCAP_ARCHIVE"
+download "$BROTLI_URL" "$BROTLI_ARCHIVE"
+
+LIBPCAP_SOURCE="$SOURCE_DIR/libpcap-${LIBPCAP_VERSION}"
+BROTLI_SOURCE="$SOURCE_DIR/brotli-${BROTLI_VERSION}"
+prepare-dir "$LIBPCAP_SOURCE"
+prepare-dir "$BROTLI_SOURCE"
+
+tar -xzf "$LIBPCAP_ARCHIVE" -C "$LIBPCAP_SOURCE" --strip-components=1
+tar -xzf "$BROTLI_ARCHIVE" -C "$BROTLI_SOURCE" --strip-components=1
+
+LIBPCAP_BUILD="$BUILD_DIR/libpcap-${ARCH}"
+BROTLI_BUILD_SOURCE="$BUILD_DIR/brotli-source-${ARCH}"
+BROTLI_BUILD_DIR="$BUILD_DIR/brotli-build-${ARCH}"
+prepare-dir "$LIBPCAP_BUILD"
+prepare-dir "$BROTLI_BUILD_SOURCE"
+prepare-dir "$BROTLI_BUILD_DIR"
+
+cp -a "$LIBPCAP_SOURCE"/. "$LIBPCAP_BUILD"/
+cp -a "$BROTLI_SOURCE"/. "$BROTLI_BUILD_SOURCE"/
+
+pushd "$LIBPCAP_BUILD" >/dev/null
+./configure \
+ --disable-shared \
+ --enable-static \
+ --without-dbus \
+ --without-libnl \
+ --without-bluetooth \
+ --without-dag \
+ --without-septel \
+ --without-snf \
+ --without-turbocap \
+ --without-rdma \
+ --without-netmap \
+ CFLAGS="-O2 -fPIC"
+make -j"$(cpu_count)"
+popd >/dev/null
+
+cmake -S "$BROTLI_BUILD_SOURCE" -B "$BROTLI_BUILD_DIR" \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DBROTLI_DISABLE_TESTS=ON \
+ -DCMAKE_POSITION_INDEPENDENT_CODE=ON
+cmake --build "$BROTLI_BUILD_DIR" --parallel "$(cpu_count)"
+
+mkdir -p "$ROOT/libs/libpcap/${ARCH}"
+mkdir -p "$ROOT/libs/libbrotli/${ARCH}"
+mkdir -p "$ROOT/libs/libpcap/src"
+mkdir -p "$ROOT/libs/libbrotli/src"
+
+cp "$LIBPCAP_BUILD/libpcap.a" "$ROOT/libs/libpcap/${ARCH}/libpcap.a"
+copy-tree "$LIBPCAP_BUILD" "$ROOT/libs/libpcap/src/libpcap"
+
+copy-static-lib "$BROTLI_BUILD_DIR/libbrotlicommon*.a" "$ROOT/libs/libbrotli/${ARCH}/libbrotlicommon.a"
+copy-static-lib "$BROTLI_BUILD_DIR/libbrotlidec*.a" "$ROOT/libs/libbrotli/${ARCH}/libbrotlidec.a"
+copy-static-lib "$BROTLI_BUILD_DIR/libbrotlienc*.a" "$ROOT/libs/libbrotli/${ARCH}/libbrotlienc.a"
+copy-tree "$BROTLI_SOURCE" "$ROOT/libs/libbrotli/src/brotli"
+
+echo "done"
+echo "generated:"
+echo " $ROOT/libs/libpcap/${ARCH}/libpcap.a"
+echo " $ROOT/libs/libbrotli/${ARCH}/libbrotlicommon.a"
+echo " $ROOT/libs/libbrotli/${ARCH}/libbrotlidec.a"
+echo " $ROOT/libs/libbrotli/${ARCH}/libbrotlienc.a"
+echo ""
+echo "next:"
+echo " cd \"$ROOT/build\" && ./build.sh linux ${ARCH} plus"
diff --git a/EdgeNode/build/build.sh b/EdgeNode/build/build.sh
index bf7991f..fb9a0f8 100644
--- a/EdgeNode/build/build.sh
+++ b/EdgeNode/build/build.sh
@@ -1,42 +1,217 @@
#!/usr/bin/env bash
+function find-binary() {
+ local candidate
+ for candidate in "$@"; do
+ if [ -z "$candidate" ]; then
+ continue
+ fi
+ if [ -x "$candidate" ]; then
+ echo "$candidate"
+ return 0
+ fi
+ if command -v "$candidate" >/dev/null 2>&1; then
+ command -v "$candidate"
+ return 0
+ fi
+ done
+ return 1
+}
+
+function host-goarch() {
+ case "$(uname -m)" in
+ x86_64|amd64)
+ echo "amd64"
+ ;;
+ aarch64|arm64)
+ echo "arm64"
+ ;;
+ i386|i486|i586|i686)
+ echo "386"
+ ;;
+ mips64)
+ echo "mips64"
+ ;;
+ mips64el)
+ echo "mips64le"
+ ;;
+ *)
+ echo ""
+ ;;
+ esac
+}
+
+function find-linux-static-toolchain() {
+ local arch=$1
+ local cc_bin=""
+ local cxx_bin=""
+ local host_arch
+
+ host_arch=$(host-goarch)
+
+ case "$arch" in
+ amd64)
+ cc_bin=$(find-binary \
+ "/usr/local/gcc/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-gcc" \
+ "/usr/local/opt/musl-cross/bin/x86_64-linux-musl-gcc" \
+ "x86_64-unknown-linux-gnu-gcc" \
+ "x86_64-linux-musl-gcc" \
+ "musl-gcc")
+ cxx_bin=$(find-binary \
+ "/usr/local/gcc/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-g++" \
+ "/usr/local/opt/musl-cross/bin/x86_64-linux-musl-g++" \
+ "x86_64-unknown-linux-gnu-g++" \
+ "x86_64-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "amd64" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "amd64" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ 386)
+ cc_bin=$(find-binary \
+ "/usr/local/opt/musl-cross/bin/i486-linux-musl-gcc" \
+ "i486-linux-musl-gcc")
+ cxx_bin=$(find-binary \
+ "/usr/local/opt/musl-cross/bin/i486-linux-musl-g++" \
+ "i486-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "386" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "386" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ arm64)
+ cc_bin=$(find-binary \
+ "/usr/local/gcc/aarch64-unknown-linux-gnu/bin/aarch64-unknown-linux-gnu-gcc" \
+ "/usr/local/opt/musl-cross/bin/aarch64-linux-musl-gcc" \
+ "aarch64-unknown-linux-gnu-gcc" \
+ "aarch64-linux-musl-gcc")
+ cxx_bin=$(find-binary \
+ "/usr/local/gcc/aarch64-unknown-linux-gnu/bin/aarch64-unknown-linux-gnu-g++" \
+ "/usr/local/opt/musl-cross/bin/aarch64-linux-musl-g++" \
+ "aarch64-unknown-linux-gnu-g++" \
+ "aarch64-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "arm64" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "arm64" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ arm)
+ cc_bin=$(find-binary \
+ "/usr/local/opt/musl-cross/bin/arm-linux-musleabi-gcc" \
+ "arm-linux-musleabi-gcc")
+ cxx_bin=$(find-binary \
+ "/usr/local/opt/musl-cross/bin/arm-linux-musleabi-g++" \
+ "arm-linux-musleabi-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "arm" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "arm" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ mips64)
+ cc_bin=$(find-binary \
+ "/usr/local/opt/musl-cross/bin/mips64-linux-musl-gcc" \
+ "mips64-linux-musl-gcc")
+ cxx_bin=$(find-binary \
+ "/usr/local/opt/musl-cross/bin/mips64-linux-musl-g++" \
+ "mips64-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "mips64" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "mips64" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ mips64le)
+ cc_bin=$(find-binary \
+ "/usr/local/opt/musl-cross/bin/mips64el-linux-musl-gcc" \
+ "mips64el-linux-musl-gcc")
+ cxx_bin=$(find-binary \
+ "/usr/local/opt/musl-cross/bin/mips64el-linux-musl-g++" \
+ "mips64el-linux-musl-g++")
+ if [ -z "$cc_bin" ] && [ "$host_arch" = "mips64le" ]; then
+ cc_bin=$(find-binary "gcc" "cc" "clang")
+ fi
+ if [ -z "$cxx_bin" ] && [ "$host_arch" = "mips64le" ]; then
+ cxx_bin=$(find-binary "g++" "c++" "clang++")
+ fi
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+
+ if [ -z "$cc_bin" ]; then
+ return 1
+ fi
+ if [ -z "$cxx_bin" ]; then
+ cxx_bin="$cc_bin"
+ fi
+
+ echo "$cc_bin|$cxx_bin"
+ return 0
+}
+
+function require-packet-static-libs() {
+ local srcdir=$1
+ local arch=$2
+ local missing=0
+ local file
+
+ for file in \
+ "${srcdir}/libs/libpcap/${arch}/libpcap.a" \
+ "${srcdir}/libs/libbrotli/${arch}/libbrotlienc.a" \
+ "${srcdir}/libs/libbrotli/${arch}/libbrotlidec.a" \
+ "${srcdir}/libs/libbrotli/${arch}/libbrotlicommon.a"; do
+ if [ ! -f "$file" ]; then
+ echo "missing required plus packet library: $file"
+ missing=1
+ fi
+ done
+
+ if [ "$missing" -ne 0 ]; then
+ return 1
+ fi
+
+ return 0
+}
+
function build() {
- ROOT=$(dirname $0)
+ ROOT=$(dirname "$0")
NAME="edge-node"
VERSION=$(lookup-version "$ROOT"/../internal/const/const.go)
DIST=$ROOT/"../dist/${NAME}"
- MUSL_DIR="/usr/local/opt/musl-cross/bin"
SRCDIR=$(realpath "$ROOT/..")
-
- # for macOS users: precompiled gcc can be downloaded from https://github.com/messense/homebrew-macos-cross-toolchains
- GCC_X86_64_DIR="/usr/local/gcc/x86_64-unknown-linux-gnu/bin"
- GCC_ARM64_DIR="/usr/local/gcc/aarch64-unknown-linux-gnu/bin"
-
OS=${1}
ARCH=${2}
TAG=${3}
if [ -z "$OS" ]; then
echo "usage: build.sh OS ARCH"
- exit
+ exit 1
fi
if [ -z "$ARCH" ]; then
echo "usage: build.sh OS ARCH"
- exit
+ exit 1
fi
if [ -z "$TAG" ]; then
TAG="community"
fi
echo "checking ..."
- ZIP_PATH=$(which zip)
- if [ -z "$ZIP_PATH" ]; then
+ if ! command -v zip >/dev/null 2>&1; then
echo "we need 'zip' command to compress files"
- exit
+ exit 1
fi
echo "building v${VERSION}/${OS}/${ARCH}/${TAG} ..."
- # 生成 zip 文件名时不包含 plus 标记
if [ "${TAG}" = "plus" ]; then
ZIP="${NAME}-${OS}-${ARCH}-v${VERSION}.zip"
else
@@ -63,11 +238,8 @@ function build() {
cp -R "$ROOT"/pages "$DIST"/
copy_fluent_bit_assets "$ROOT" "$DIST" "$OS" "$ARCH" || exit 1
- # we support TOA on linux only
- if [ "$OS" == "linux" ] && [ -f "${ROOT}/edge-toa/edge-toa-${ARCH}" ]
- then
- if [ ! -d "$DIST/edge-toa" ]
- then
+ if [ "$OS" == "linux" ] && [ -f "${ROOT}/edge-toa/edge-toa-${ARCH}" ]; then
+ if [ ! -d "$DIST/edge-toa" ]; then
mkdir "$DIST/edge-toa"
fi
cp "${ROOT}/edge-toa/edge-toa-${ARCH}" "$DIST/edge-toa/edge-toa"
@@ -75,96 +247,59 @@ function build() {
echo "building ..."
- CC_PATH=""
- CXX_PATH=""
+ CC_BIN=""
+ CXX_BIN=""
CGO_LDFLAGS=""
CGO_CFLAGS=""
BUILD_TAG=$TAG
- if [[ `uname -a` == *"Darwin"* && "${OS}" == "linux" ]]; then
- if [ "${ARCH}" == "amd64" ]; then
- # build with script support
- if [ -d $GCC_X86_64_DIR ]; then
- MUSL_DIR=$GCC_X86_64_DIR
- CC_PATH="x86_64-unknown-linux-gnu-gcc"
- CXX_PATH="x86_64-unknown-linux-gnu-g++"
- if [ "$TAG" = "plus" ]; then
- BUILD_TAG="plus,script,packet"
- fi
- else
- CC_PATH="x86_64-linux-musl-gcc"
- CXX_PATH="x86_64-linux-musl-g++"
- fi
- fi
- if [ "${ARCH}" == "386" ]; then
- CC_PATH="i486-linux-musl-gcc"
- CXX_PATH="i486-linux-musl-g++"
- fi
- if [ "${ARCH}" == "arm64" ]; then
- # build with script support
- if [ -d $GCC_ARM64_DIR ]; then
- MUSL_DIR=$GCC_ARM64_DIR
- CC_PATH="aarch64-unknown-linux-gnu-gcc"
- CXX_PATH="aarch64-unknown-linux-gnu-g++"
- if [ "$TAG" = "plus" ]; then
- BUILD_TAG="plus,script,packet"
- fi
- else
- CC_PATH="aarch64-linux-musl-gcc"
- CXX_PATH="aarch64-linux-musl-g++"
- fi
- fi
- if [ "${ARCH}" == "arm" ]; then
- CC_PATH="arm-linux-musleabi-gcc"
- CXX_PATH="arm-linux-musleabi-g++"
- fi
- if [ "${ARCH}" == "mips64" ]; then
- CC_PATH="mips64-linux-musl-gcc"
- CXX_PATH="mips64-linux-musl-g++"
- fi
- if [ "${ARCH}" == "mips64le" ]; then
- CC_PATH="mips64el-linux-musl-gcc"
- CXX_PATH="mips64el-linux-musl-g++"
- fi
- fi
- # libpcap
- if [ "$OS" == "linux" ] && [[ "$ARCH" == "amd64" || "$ARCH" == "arm64" ]] && [ "$TAG" == "plus" ]; then
+ if [ "$OS" == "linux" ] && [[ "$ARCH" == "amd64" || "$ARCH" == "arm64" ]] && [ "$TAG" == "plus" ]; then
+ require-packet-static-libs "$SRCDIR" "$ARCH" || exit 1
+ BUILD_TAG="plus,script,packet"
CGO_LDFLAGS="-L${SRCDIR}/libs/libpcap/${ARCH} -lpcap -L${SRCDIR}/libs/libbrotli/${ARCH} -lbrotlienc -lbrotlidec -lbrotlicommon"
CGO_CFLAGS="-I${SRCDIR}/libs/libpcap/src/libpcap -I${SRCDIR}/libs/libpcap/src/libpcap/pcap -I${SRCDIR}/libs/libbrotli/src/brotli/c/include -I${SRCDIR}/libs/libbrotli/src/brotli/c/include/brotli"
fi
- if [ ! -z $CC_PATH ]; then
- env CC=$MUSL_DIR/$CC_PATH \
- CXX=$MUSL_DIR/$CXX_PATH GOOS="${OS}" \
- GOARCH="${ARCH}" CGO_ENABLED=1 \
- CGO_LDFLAGS="${CGO_LDFLAGS}" \
- CGO_CFLAGS="${CGO_CFLAGS}" \
- go build -trimpath -tags $BUILD_TAG -o "$DIST"/bin/${NAME} -ldflags "-linkmode external -extldflags -static -s -w" "$ROOT"/../cmd/edge-node/main.go
- else
- if [[ `uname` == *"Linux"* ]] && [ "$OS" == "linux" ] && [[ "$ARCH" == "amd64" || "$ARCH" == "arm64" ]] && [ "$TAG" == "plus" ]; then
- BUILD_TAG="plus,script,packet"
+ if [ "$OS" == "linux" ]; then
+ TOOLCHAIN=$(find-linux-static-toolchain "$ARCH")
+ if [ -z "$TOOLCHAIN" ]; then
+ echo "could not find a static Linux toolchain for ${ARCH}"
+ echo "install a musl cross compiler or provide /usr/local/gcc toolchains before building"
+ exit 1
fi
- env GOOS="${OS}" GOARCH="${ARCH}" CGO_ENABLED=1 CGO_LDFLAGS="${CGO_LDFLAGS}" CGO_CFLAGS="${CGO_CFLAGS}" go build -trimpath -tags $BUILD_TAG -o "$DIST"/bin/${NAME} -ldflags="-s -w" "$ROOT"/../cmd/edge-node/main.go
+ CC_BIN=${TOOLCHAIN%|*}
+ CXX_BIN=${TOOLCHAIN#*|}
+
+ env CC="$CC_BIN" \
+ CXX="$CXX_BIN" \
+ GOOS="${OS}" \
+ GOARCH="${ARCH}" \
+ CGO_ENABLED=1 \
+ CGO_LDFLAGS="${CGO_LDFLAGS}" \
+ CGO_CFLAGS="${CGO_CFLAGS}" \
+ go build -trimpath -tags "$BUILD_TAG" -o "$DIST"/bin/${NAME} -ldflags "-linkmode external -extldflags -static -s -w" "$ROOT"/../cmd/edge-node/main.go
+ else
+ env GOOS="${OS}" GOARCH="${ARCH}" CGO_ENABLED=1 CGO_LDFLAGS="${CGO_LDFLAGS}" CGO_CFLAGS="${CGO_CFLAGS}" \
+ go build -trimpath -tags "$BUILD_TAG" -o "$DIST"/bin/${NAME} -ldflags="-s -w" "$ROOT"/../cmd/edge-node/main.go
fi
if [ ! -f "${DIST}/bin/${NAME}" ]; then
echo "build failed!"
- exit
+ exit 1
fi
- # delete hidden files
find "$DIST" -name ".DS_Store" -delete
find "$DIST" -name ".gitignore" -delete
echo "zip files"
- cd "${DIST}/../" || exit
+ cd "${DIST}/../" || exit 1
if [ -f "${ZIP}" ]; then
rm -f "${ZIP}"
fi
zip -r -X -q "${ZIP}" ${NAME}/
rm -rf ${NAME}
- cd - || exit
+ cd - || exit 1
echo "OK"
}
@@ -253,7 +388,7 @@ function lookup-version() {
echo "$VERSION"
else
echo "could not match version"
- exit
+ exit 1
fi
}
diff --git a/EdgeNode/build/data/disk.speed.json b/EdgeNode/build/data/disk.speed.json
index 8ed61c3..30eda56 100644
--- a/EdgeNode/build/data/disk.speed.json
+++ b/EdgeNode/build/data/disk.speed.json
@@ -1 +1 @@
-{"speed":1,"speedMB":1400,"countTests":3}
\ No newline at end of file
+{"speed":1,"speedMB":1510,"countTests":10}
\ No newline at end of file
diff --git a/EdgeNode/build/sudo-run-plus.sh b/EdgeNode/build/sudo-run-plus.sh
index 504f632..c928833 100644
--- a/EdgeNode/build/sudo-run-plus.sh
+++ b/EdgeNode/build/sudo-run-plus.sh
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
-sudo go run -tags="plus script packet" ../cmd/edge-node/main.go
\ No newline at end of file
+sudo go run -tags="plus script" ../cmd/edge-node/main.go
diff --git a/EdgeNode/go.mod b/EdgeNode/go.mod
index 797b2d3..9c23502 100644
--- a/EdgeNode/go.mod
+++ b/EdgeNode/go.mod
@@ -20,7 +20,6 @@ require (
github.com/dchest/captcha v0.0.0-00010101000000-000000000000
github.com/fsnotify/fsnotify v1.7.0
github.com/go-redis/redis/v8 v8.11.5
- github.com/google/gopacket v1.1.19
github.com/google/nftables v0.2.0
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible
github.com/iwind/TeaGo v0.0.0-20240411075713-6c1fc9aca7b6
diff --git a/EdgeNode/go.sum b/EdgeNode/go.sum
index ba857d7..bd6df05 100644
--- a/EdgeNode/go.sum
+++ b/EdgeNode/go.sum
@@ -67,8 +67,6 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
-github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
-github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/nftables v0.2.0 h1:PbJwaBmbVLzpeldoeUKGkE2RjstrjPKMl6oLrfEJ6/8=
github.com/google/nftables v0.2.0/go.mod h1:Beg6V6zZ3oEn0JuiUQ4wqwuyqqzasOltcoXPtgLbFp4=
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 h1:y3N7Bm7Y9/CtpiVkw/ZWj6lSlDF3F74SfKwfTCer72Q=
diff --git a/EdgeNode/internal/const/const.go b/EdgeNode/internal/const/const.go
index ae07326..da970cc 100644
--- a/EdgeNode/internal/const/const.go
+++ b/EdgeNode/internal/const/const.go
@@ -1,7 +1,7 @@
package teaconst
const (
- Version = "1.4.9" //1.3.8.2
+ Version = "1.5.0" //1.3.8.2
ProductName = "Edge Node"
ProcessName = "edge-node"
diff --git a/EdgeNode/internal/network-security/manager.go b/EdgeNode/internal/network-security/manager.go
deleted file mode 100644
index c43b06e..0000000
--- a/EdgeNode/internal/network-security/manager.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && packet
-
-package networksecurity
-
-import (
- "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
- teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
- "github.com/TeaOSLab/EdgeNode/internal/events"
- "github.com/TeaOSLab/EdgeNode/internal/monitor"
- "github.com/TeaOSLab/EdgeNode/internal/remotelogs"
- "github.com/TeaOSLab/EdgeNode/internal/utils"
- "github.com/TeaOSLab/EdgeNode/internal/utils/goman"
- "github.com/TeaOSLab/EdgeNode/internal/utils/netpackets"
- "github.com/iwind/TeaGo/Tea"
- "github.com/iwind/TeaGo/maps"
- "runtime"
- "time"
-)
-
-var SharedManager = NewManager()
-
-func init() {
- if !teaconst.IsMain {
- return
- }
-
- events.On(events.EventLoaded, func() {
- nodeConfig, _ := nodeconfigs.SharedNodeConfig()
- if nodeConfig != nil {
- go SharedManager.Apply(nodeConfig.NetworkSecurityPolicy)
- }
- })
-
- events.On(events.EventQuit, func() {
- go SharedManager.Apply(nil)
- })
-
- goman.New(func() {
- var ticker = time.NewTicker(1 * time.Minute)
- for range ticker.C {
- SharedManager.Upload()
- }
- })
-}
-
-type Manager struct {
- listener *netpackets.Listener
- isRunning bool
-
- policy *nodeconfigs.NetworkSecurityPolicy
-
- totalTCPPacketsMinutely uint64
- totalUDPPacketsMinutely uint64
- totalICMPPacketsMinutely uint64
-}
-
-func NewManager() *Manager {
- return &Manager{}
-}
-
-// Apply 应用配置
-// 非线程安全
-func (this *Manager) Apply(policy *nodeconfigs.NetworkSecurityPolicy) {
- if this.policy != nil && this.policy.IsSame(policy) {
- return
- }
-
- this.policy = policy
-
- if policy == nil ||
- policy.Status == nodeconfigs.NetworkSecurityStatusOff ||
- (policy.Status == nodeconfigs.NetworkSecurityStatusAuto && runtime.NumCPU() < 8) {
- if this.listener != nil {
- remotelogs.Println("NETWORK_SECURITY_MANAGER", "stop")
- this.listener.Stop()
- }
- this.isRunning = false
- return
- }
-
- if this.listener == nil {
- this.listener = netpackets.NewListener()
-
- // References:
- // - https://biot.com/capstats/bpf.html
- // - https://www.ibm.com/docs/en/qsip/7.4?topic=queries-berkeley-packet-filters
- // - https://www.tcpdump.org/manpages/tcpdump.1.html
-
- if Tea.IsTesting() || utils.IsDebugEnv() { // dev environment
- this.listener.SetBPF("(tcp or udp or icmp) and not net 127 and not net ::1")
- } else {
- this.listener.SetBPF("(tcp or udp or icmp) and not src net 127 and not src net 192.168 and not src net 172.16 and not src net ::1 and not src net 10")
- }
- this.listener.AddFilter(this)
- }
-
- if !this.isRunning {
- this.isRunning = true
- remotelogs.Println("NETWORK_SECURITY_MANAGER", "start")
- err := this.listener.Start() // long run function
- if err != nil {
- remotelogs.Error("NETWORK_SECURITY_MANAGER", "start listener failed: "+err.Error())
- }
- this.isRunning = false
- }
-}
-
-func (this *Manager) FilterMeta(meta *netpackets.PacketMeta) {
- switch meta.LayerType {
- case netpackets.LayerTypeTCP:
- // 这里不需要试用atomic,因为数据不需要那么精确
- this.totalTCPPacketsMinutely++
- case netpackets.LayerTypeUDP:
- this.totalUDPPacketsMinutely++
- case netpackets.LayerTypeICMPv4, netpackets.LayerTypeICMPv6:
- this.totalICMPPacketsMinutely++
- }
-}
-
-func (this *Manager) Upload() {
- if !this.isRunning {
- return
- }
-
- monitor.SharedValueQueue.Add(nodeconfigs.NodeValueItemNetworkPackets, maps.Map{
- "tcpInPPS": this.totalTCPPacketsMinutely / 60,
- "udpInPPS": this.totalUDPPacketsMinutely / 60,
- "icmpInPPS": this.totalICMPPacketsMinutely / 60,
- })
-
- this.totalTCPPacketsMinutely = 0
- this.totalUDPPacketsMinutely = 0
- this.totalICMPPacketsMinutely = 0
-}
diff --git a/EdgeNode/internal/network-security/manager_test.go b/EdgeNode/internal/network-security/manager_test.go
deleted file mode 100644
index f8238ca..0000000
--- a/EdgeNode/internal/network-security/manager_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && packet
-
-package networksecurity_test
-
-import (
- "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
- networksecurity "github.com/TeaOSLab/EdgeNode/internal/network-security"
- "github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
- "os"
- "testing"
-)
-
-func TestManager_Apply(t *testing.T) {
- if !testutils.IsSingleTesting() {
- if os.Getgid() > 0 {
- return
- }
- }
-
- var manager = networksecurity.NewManager()
- var policy = nodeconfigs.NewNetworkSecurityPolicy()
- manager.Apply(policy)
-}
diff --git a/EdgeNode/internal/network-security/manager_test.sh b/EdgeNode/internal/network-security/manager_test.sh
deleted file mode 100644
index 827b691..0000000
--- a/EdgeNode/internal/network-security/manager_test.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env bash
-
-sudo go test -v -tags="plus packet" -run '^TestManager_Apply'
\ No newline at end of file
diff --git a/EdgeNode/internal/nodes/http_request_auth.go b/EdgeNode/internal/nodes/http_request_auth.go
index a8ac153..595de03 100644
--- a/EdgeNode/internal/nodes/http_request_auth.go
+++ b/EdgeNode/internal/nodes/http_request_auth.go
@@ -9,14 +9,20 @@ import (
"net/http"
)
-// 执行认证
+// 鎵ц璁よ瘉
func (this *HTTPRequest) doAuth() (shouldStop bool) {
if this.web.Auth == nil || !this.web.Auth.IsOn {
return
}
for _, ref := range this.web.Auth.PolicyRefs {
- if !ref.IsOn || ref.AuthPolicy == nil || !ref.AuthPolicy.IsOn {
+ if !ref.IsOn {
+ continue
+ }
+ if ref.AuthPolicy == nil {
+ continue
+ }
+ if !ref.AuthPolicy.IsOn {
continue
}
if !ref.AuthPolicy.MatchRequest(this.RawReq) {
@@ -36,7 +42,7 @@ func (this *HTTPRequest) doAuth() (shouldStop bool) {
return writer.StatusCode(), nil
}, this.Format)
if err != nil {
- this.write50x(err, http.StatusInternalServerError, "Failed to execute the AuthPolicy", "认证策略执行失败", false)
+ this.write50x(err, http.StatusInternalServerError, "Failed to execute the AuthPolicy", "璁よ瘉绛栫暐鎵ц澶辫触", false)
return
}
if ok {
@@ -45,28 +51,28 @@ func (this *HTTPRequest) doAuth() (shouldStop bool) {
}
this.tags = append(this.tags, "auth:"+ref.AuthPolicy.Type)
return
- } else {
- // Basic Auth比较特殊
- if ref.AuthPolicy.Type == serverconfigs.HTTPAuthTypeBasicAuth {
- method, ok := ref.AuthPolicy.Method().(*serverconfigs.HTTPAuthBasicMethod)
- if ok {
- var headerValue = "Basic realm=\""
- if len(method.Realm) > 0 {
- headerValue += method.Realm
- } else {
- headerValue += this.ReqHost
- }
- headerValue += "\""
- if len(method.Charset) > 0 {
- headerValue += ", charset=\"" + method.Charset + "\""
- }
- this.writer.Header()["WWW-Authenticate"] = []string{headerValue}
- }
- }
- this.writer.WriteHeader(http.StatusUnauthorized)
- this.tags = append(this.tags, "auth:"+ref.AuthPolicy.Type)
- return true
}
+
+ // Basic Auth 姣旇緝鐗规畩
+ if ref.AuthPolicy.Type == serverconfigs.HTTPAuthTypeBasicAuth {
+ method, ok := ref.AuthPolicy.Method().(*serverconfigs.HTTPAuthBasicMethod)
+ if ok {
+ var headerValue = "Basic realm=\""
+ if len(method.Realm) > 0 {
+ headerValue += method.Realm
+ } else {
+ headerValue += this.ReqHost
+ }
+ headerValue += "\""
+ if len(method.Charset) > 0 {
+ headerValue += ", charset=\"" + method.Charset + "\""
+ }
+ this.writer.Header()["WWW-Authenticate"] = []string{headerValue}
+ }
+ }
+ this.writer.WriteHeader(http.StatusUnauthorized)
+ this.tags = append(this.tags, "auth:"+ref.AuthPolicy.Type)
+ return true
}
return
}
diff --git a/EdgeNode/internal/nodes/node_tasks_packet_plus.go b/EdgeNode/internal/nodes/node_tasks_packet_plus.go
deleted file mode 100644
index 867d4df..0000000
--- a/EdgeNode/internal/nodes/node_tasks_packet_plus.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && packet
-
-package nodes
-
-import (
- "encoding/json"
- "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
- "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
- networksecurity "github.com/TeaOSLab/EdgeNode/internal/network-security"
- "github.com/TeaOSLab/EdgeNode/internal/remotelogs"
- "github.com/TeaOSLab/EdgeNode/internal/rpc"
-)
-
-func (this *Node) execNetworkSecurityPolicyChangedTask(rpcClient *rpc.RPCClient) error {
- remotelogs.Println("NODE", "updating network security policy ...")
- resp, err := rpcClient.NodeRPC.FindNodeNetworkSecurityPolicy(rpcClient.Context(), &pb.FindNodeNetworkSecurityPolicyRequest{})
- if err != nil {
- return err
- }
-
- var policy = nodeconfigs.NewNetworkSecurityPolicy()
- if len(resp.NetworkSecurityPolicyJSON) > 0 {
- err = json.Unmarshal(resp.NetworkSecurityPolicyJSON, policy)
- if err != nil {
- return err
- }
- }
-
- sharedNodeConfig.NetworkSecurityPolicy = policy
-
- go networksecurity.SharedManager.Apply(policy)
-
- return nil
-}
diff --git a/EdgeNode/internal/nodes/node_tasks_packet_stub_plus.go b/EdgeNode/internal/nodes/node_tasks_packet_stub_plus.go
index edd1f73..0795cc1 100644
--- a/EdgeNode/internal/nodes/node_tasks_packet_stub_plus.go
+++ b/EdgeNode/internal/nodes/node_tasks_packet_stub_plus.go
@@ -1,5 +1,5 @@
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && !packet
+//go:build plus
package nodes
diff --git a/EdgeNode/internal/utils/netpackets/filter_interface.go b/EdgeNode/internal/utils/netpackets/filter_interface.go
deleted file mode 100644
index cc3e18e..0000000
--- a/EdgeNode/internal/utils/netpackets/filter_interface.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && packet
-
-package netpackets
-
-type FilterInterface interface {
- FilterMeta(meta *PacketMeta)
-}
diff --git a/EdgeNode/internal/utils/netpackets/ignored_ip_list.go b/EdgeNode/internal/utils/netpackets/ignored_ip_list.go
deleted file mode 100644
index 89ce7e6..0000000
--- a/EdgeNode/internal/utils/netpackets/ignored_ip_list.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus
-
-package netpackets
-
-import (
- "github.com/TeaOSLab/EdgeNode/internal/utils/linkedlist"
- "sync"
-)
-
-type IgnoredIPList struct {
- mu sync.RWMutex
-
- itemMap map[string]*linkedlist.Item[string] // linked => item
- list *linkedlist.List[string]
-
- capacity int
- lastIP string
-}
-
-func NewIgnoredIPList(capacity int) *IgnoredIPList {
- return &IgnoredIPList{
- itemMap: map[string]*linkedlist.Item[string]{},
- list: linkedlist.NewList[string](),
- capacity: capacity,
- }
-}
-
-func (this *IgnoredIPList) Add(ip string) {
- this.mu.Lock()
- defer this.mu.Unlock()
-
- if this.lastIP == ip {
- return
- }
- this.lastIP = ip
-
- item, ok := this.itemMap[ip]
- if !ok {
- if this.capacity > 0 && len(this.itemMap) == this.capacity {
- var firstItem = this.list.Shift()
- if firstItem != nil {
- delete(this.itemMap, firstItem.Value)
- }
- }
-
- item = linkedlist.NewItem[string](ip)
- this.itemMap[ip] = item
- }
- this.list.Push(item)
-}
-
-func (this *IgnoredIPList) Remove(ip string) {
- this.mu.Lock()
- defer this.mu.Unlock()
-
- item, ok := this.itemMap[ip]
- if ok {
- delete(this.itemMap, ip)
- this.list.Remove(item)
- }
-}
-
-func (this *IgnoredIPList) Contains(ip string) bool {
- this.mu.RLock()
- defer this.mu.RUnlock()
- _, ok := this.itemMap[ip]
- return ok
-}
-
-func (this *IgnoredIPList) List(size int) (ipList []string) {
- if size <= 0 {
- return
- }
-
- this.mu.RLock()
- defer this.mu.RUnlock()
-
- this.list.RangeReverse(func(item *linkedlist.Item[string]) (goNext bool) {
- ipList = append(ipList, item.Value)
- size--
- return size > 0
- })
-
- return
-}
-
-func (this *IgnoredIPList) Len() int {
- this.mu.RLock()
- defer this.mu.RUnlock()
- return len(this.itemMap)
-}
diff --git a/EdgeNode/internal/utils/netpackets/ignored_ip_list_test.go b/EdgeNode/internal/utils/netpackets/ignored_ip_list_test.go
deleted file mode 100644
index ee0f23b..0000000
--- a/EdgeNode/internal/utils/netpackets/ignored_ip_list_test.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus
-
-package netpackets_test
-
-import (
- "fmt"
- "github.com/TeaOSLab/EdgeNode/internal/utils/netpackets"
- "github.com/iwind/TeaGo/assert"
- "github.com/iwind/TeaGo/rands"
- "runtime"
- "testing"
-)
-
-func TestIgnoredIPList_Add(t *testing.T) {
- var a = assert.NewAssertion(t)
-
- var list = netpackets.NewIgnoredIPList(10)
- list.Add("192.168.2.1")
- list.Add("192.168.2.2")
- list.Add("192.168.2.3")
-
- a.IsTrue(list.Contains("192.168.2.1"))
- a.IsFalse(list.Contains("192.168.2.0"))
-
- t.Log(list.List(0))
- t.Log(list.List(2))
- t.Log(list.List(4))
-}
-
-func TestIgnoredIPList_Add_Capacity(t *testing.T) {
- var list = netpackets.NewIgnoredIPList(4)
- list.Add("192.168.2.1")
- list.Add("192.168.2.2")
- list.Add("192.168.2.3")
- list.Add("192.168.2.4")
- list.Add("192.168.2.5")
- list.Add("192.168.2.6")
- list.Add("192.168.2.7")
- t.Log(list.List(10))
- t.Log(list.Len(), "items")
-}
-
-func TestIgnoredIPList_Remove(t *testing.T) {
- var list = netpackets.NewIgnoredIPList(10)
- list.Add("192.168.2.1")
- list.Add("192.168.2.2")
- list.Add("192.168.2.3")
- list.Remove("192.168.2.2")
- t.Log(list.List(4))
-}
-
-func BenchmarkIgnoredIPList_Add(b *testing.B) {
- runtime.GOMAXPROCS(1)
-
- var genIPFunc = func() string {
- return fmt.Sprintf("%d.%d.%d.%d", rands.Int(0, 255), rands.Int(0, 255), rands.Int(0, 255), rands.Int(0, 255))
- }
-
- var list = netpackets.NewIgnoredIPList(65535)
- b.RunParallel(func(pb *testing.PB) {
- for pb.Next() {
- list.Add(genIPFunc())
- list.Remove(genIPFunc())
- list.Contains(genIPFunc())
- if rands.Int(0, 100) == 0 {
- list.List(1000)
- }
- }
- })
-}
diff --git a/EdgeNode/internal/utils/netpackets/layer_type.go b/EdgeNode/internal/utils/netpackets/layer_type.go
deleted file mode 100644
index 44f95bd..0000000
--- a/EdgeNode/internal/utils/netpackets/layer_type.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && packet
-
-package netpackets
-
-import (
- "github.com/google/gopacket"
- "github.com/google/gopacket/layers"
-)
-
-type LayerType = gopacket.LayerType
-
-var (
- LayerTypeTCP = layers.LayerTypeTCP
- LayerTypeUDP = layers.LayerTypeUDP
- LayerTypeICMPv4 = layers.LayerTypeICMPv4
- LayerTypeICMPv6 = layers.LayerTypeICMPv6
-)
diff --git a/EdgeNode/internal/utils/netpackets/listener.go b/EdgeNode/internal/utils/netpackets/listener.go
deleted file mode 100644
index d6c0d88..0000000
--- a/EdgeNode/internal/utils/netpackets/listener.go
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && packet
-
-package netpackets
-
-import (
- "encoding/binary"
- "fmt"
- "github.com/TeaOSLab/EdgeNode/internal/remotelogs"
- "github.com/TeaOSLab/EdgeNode/internal/utils"
- "github.com/google/gopacket"
- "github.com/google/gopacket/layers"
- "github.com/google/gopacket/pcap"
- "sort"
- "strings"
- "time"
-)
-
-const defaultBPFFilter = "(tcp or udp or icmp) and not net 127.0.0.1"
-
-type Listener struct {
- filters []FilterInterface
- incomingHandle *pcap.Handle
- bpfFilter string
-
- decodeDstIP bool
-
- isClosed bool
-
- outgoingIPList *IgnoredIPList
- outgoingHandle *pcap.Handle
-
- filterTicker *time.Ticker
-}
-
-func NewListener() *Listener {
- return &Listener{
- isClosed: true,
- outgoingIPList: NewIgnoredIPList(65535),
- }
-}
-
-func (this *Listener) Start() error {
- if !this.isClosed {
- return nil
- }
-
- this.isClosed = false
-
- go func() {
- startErr := this.loopOutgoing()
- if startErr != nil {
- remotelogs.Error("NET_PACKET", "start outgoing packet listener failed: "+startErr.Error())
- }
- }()
-
- go func() {
- this.loopUpdateFilter()
- }()
-
- for { // 无限 for 是为了防止意外退出
- err := this.loopIncoming()
- if err != nil {
- if this.isClosed {
- return nil
- }
-
- return fmt.Errorf("start packet listener failed: %w", err)
- }
-
- if this.isClosed {
- return nil
- }
- }
-}
-
-func (this *Listener) AddFilter(filter FilterInterface) {
- this.filters = append(this.filters, filter)
-}
-
-func (this *Listener) SetBPF(bpfFilter string) {
- this.bpfFilter = bpfFilter
-}
-
-func (this *Listener) DecodeDstIP() {
- this.decodeDstIP = true
-}
-
-func (this *Listener) Stop() {
- this.isClosed = true
- this.incomingHandle.Close()
- this.outgoingHandle.Close()
-}
-
-func (this *Listener) IsRunning() bool {
- return this.incomingHandle != nil && !this.isClosed
-}
-
-func (this *Listener) loopIncoming() error {
- const device = "any"
- var err error
- this.incomingHandle, err = pcap.OpenLive(device, 128, false /** ignore collision domain **/, pcap.BlockForever)
- if err != nil {
- return err
- }
-
- defer func() {
- this.incomingHandle.Close()
- }()
-
- err = this.incomingHandle.SetDirection(pcap.DirectionIn)
- if err != nil {
- return err
- }
-
- if len(this.bpfFilter) > 0 {
- err = this.incomingHandle.SetBPFFilter(this.bpfFilter)
- } else {
- this.bpfFilter = defaultBPFFilter
- err = this.incomingHandle.SetBPFFilter(defaultBPFFilter)
- }
- if err != nil {
- return err
- }
-
- var meta = &PacketMeta{}
-
- var packetSource = gopacket.NewPacketSource(this.incomingHandle, this.incomingHandle.LinkType())
- packetSource.NoCopy = true
- packetSource.Lazy = true
-
- var filters = this.filters
- var countFilters = len(filters)
-
- for packet := range packetSource.Packets() {
- var networkLayer = packet.NetworkLayer()
- if networkLayer == nil {
- continue
- }
-
- var networkFlow = networkLayer.NetworkFlow()
-
- var src = networkFlow.Src()
-
- meta.SrcIP = src.String()
-
- // ignore outgoing ip
- if this.outgoingIPList.Contains(meta.SrcIP) {
- continue
- }
-
- if this.decodeDstIP {
- meta.DstIP = networkFlow.Dst().String()
- }
- meta.Length = packet.Metadata().Length
-
- var transportLayer = packet.TransportLayer()
- if transportLayer == nil {
- meta.SrcPort = 0
- meta.DstPort = 0
-
- switch x := networkLayer.(type) {
- case *layers.IPv4:
- meta.LayerType = x.NextLayerType()
- case *layers.IPv6:
- meta.LayerType = x.NextLayerType()
- }
-
- // call filters
- if countFilters == 1 {
- filters[0].FilterMeta(meta)
- } else {
- for _, filter := range filters {
- filter.FilterMeta(meta)
- }
- }
-
- continue
- }
-
- var transportFlow = transportLayer.TransportFlow()
- meta.SrcPort = int(binary.BigEndian.Uint16(transportFlow.Src().Raw()))
- meta.LayerType = transportLayer.LayerType()
- meta.DstPort = int(binary.BigEndian.Uint16(transportFlow.Dst().Raw()))
-
- // call filters
- if countFilters == 1 {
- filters[0].FilterMeta(meta)
- } else {
- for _, filter := range filters {
- filter.FilterMeta(meta)
- }
- }
- }
-
- return nil
-}
-
-func (this *Listener) loopOutgoing() error {
- const device = "any"
- var err error
- this.outgoingHandle, err = pcap.OpenLive(device, 128, true /** ignore collision domain **/, pcap.BlockForever)
-
- if err != nil {
- return err
- }
-
- defer func() {
- this.outgoingHandle.Close()
- }()
-
- err = this.outgoingHandle.SetDirection(pcap.DirectionOut)
- if err != nil {
- return err
- }
-
- err = this.outgoingHandle.SetBPFFilter("tcp and tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) = 0")
- if err != nil {
- return err
- }
-
- var packetSource = gopacket.NewPacketSource(this.outgoingHandle, this.outgoingHandle.LinkType())
- packetSource.NoCopy = true
- packetSource.Lazy = true
-
- for packet := range packetSource.Packets() {
- var networkLayer = packet.NetworkLayer()
- if networkLayer == nil {
- continue
- }
-
- var networkFlow = networkLayer.NetworkFlow()
- var dstIP = networkFlow.Dst().String()
- this.outgoingIPList.Add(dstIP)
- }
-
- return nil
-}
-
-func (this *Listener) loopUpdateFilter() {
- if this.filterTicker != nil {
- return
- }
-
- this.filterTicker = time.NewTicker(1 * time.Second)
- var lastIPList []string
- for range this.filterTicker.C {
- if this.isClosed {
- continue
- }
-
- var ipList = this.outgoingIPList.List(512) // 基于bfp长度的限制,这里数量不能太多
- sort.Strings(ipList)
- if this.equalStrings(lastIPList, ipList) {
- continue
- }
-
- lastIPList = ipList
-
- // apply
- var incomingHandle = this.incomingHandle
- if incomingHandle != nil {
- var rules = []string{}
- for _, ip := range ipList {
- rules = append(rules, "not src host "+ip)
- }
- var newBPFFilter = this.bpfFilter + " and " + strings.Join(rules, " and ")
- if utils.IsDebugEnv() {
- remotelogs.Debug("NET_PACKET", "set new BPF filter: "+newBPFFilter)
- }
- err := incomingHandle.SetBPFFilter(newBPFFilter)
- if err != nil {
- remotelogs.Error("NET_PACKET", "set new BPF filter failed: "+err.Error())
- }
- }
- }
-}
-
-func (this *Listener) equalStrings(s1 []string, s2 []string) bool {
- var l = len(s1)
- if len(s2) != l {
- return false
- }
- if l == 0 {
- return true
- }
- for i := 0; i < l; i++ {
- if s1[i] != s2[i] {
- return false
- }
- }
- return true
-}
diff --git a/EdgeNode/internal/utils/netpackets/listener_test.go b/EdgeNode/internal/utils/netpackets/listener_test.go
deleted file mode 100644
index 2717398..0000000
--- a/EdgeNode/internal/utils/netpackets/listener_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && packet
-
-package netpackets_test
-
-import (
- "encoding/binary"
- "github.com/TeaOSLab/EdgeNode/internal/utils/netpackets"
- "github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
- "github.com/google/gopacket"
- "github.com/google/gopacket/layers"
- "github.com/iwind/TeaGo/types"
- "log"
- "os"
- "testing"
- "time"
-)
-
-type testFilter struct {
-}
-
-func (this *testFilter) FilterMeta(meta *netpackets.PacketMeta) {
- log.Println(meta.LayerType.String() + " " + meta.SrcIP + ":" + types.String(meta.SrcPort) + " => " + meta.DstIP + ":" + types.String(meta.DstPort) + " " + types.String(meta.Length) + "bytes")
-}
-
-func TestListener_Start(t *testing.T) {
- if !testutils.IsSingleTesting() {
- if os.Getgid() > 0 {
- return
- }
- }
-
- var listener = netpackets.NewListener()
- listener.AddFilter(&testFilter{})
-
- go func() {
- time.Sleep(10 * time.Second)
- t.Log("stopping ...")
- listener.Stop()
- }()
-
- t.Log("starting ...")
- err := listener.Start()
- if err != nil {
- t.Fatal(err)
- }
-}
-
-func TestListener_DecodePacket_UDP(t *testing.T) {
- var packetData = []byte{69, 0, 0, 134, 140, 133, 0, 0, 118, 17, 16, 79, 223, 5, 5, 5, 192, 168, 2, 224, 0, 53, 232, 163, 0, 114, 0, 0, 69, 42, 129, 128, 0, 1, 0, 3, 0, 0, 0, 0, 6, 115, 116, 97, 116, 105, 99, 7, 111, 115, 99, 104, 105, 110, 97, 3, 110, 101, 116, 0, 0, 1, 0, 1, 192, 12, 0, 5, 0, 1, 0, 0, 0, 1, 0, 25, 10, 115, 116, 97, 116, 105, 99, 45, 111, 115, 99, 2, 98, 48, 5, 97, 105, 99, 100, 110, 3, 99, 111, 109, 0, 192, 48, 0, 5, 0, 1, 0, 0, 0, 1, 0, 5, 2, 118, 109, 192, 62, 192, 85, 0, 1, 0, 1, 0, 0, 0, 1, 0, 4, 218, 28, 104, 157}
-
- var packet = gopacket.NewPacket(packetData, layers.LayerTypeIPv4, gopacket.DecodeOptions{})
- var networkFlow = packet.NetworkLayer().NetworkFlow()
-
- t.Log(networkFlow)
-
- t.Log(packet.Metadata().Length)
- t.Log(packet.TransportLayer().TransportFlow())
-}
-
-func TestListener_DecodePacket_TCP(t *testing.T) {
- var packetData = []byte{69, 8, 0, 64, 6, 51, 64, 0, 52, 6, 188, 222, 74, 91, 117, 187, 192, 168, 2, 224, 1, 187, 225, 226, 137, 198, 251, 25, 221, 137, 133, 93, 176, 16, 1, 245, 224, 6, 0, 0, 1, 1, 8, 10, 30, 187, 162, 175, 35, 215, 100, 174, 1, 1, 5, 10, 221, 137, 133, 68, 221, 137, 133, 93}
-
- var packet = gopacket.NewPacket(packetData, layers.LayerTypeIPv4, gopacket.DecodeOptions{})
- var networkFlow = packet.NetworkLayer().NetworkFlow()
- t.Log(networkFlow.Src().Raw(), len(networkFlow.Src().Raw()))
-
- t.Log(networkFlow)
-
- t.Log(packet.Metadata().Length)
- t.Log(packet.TransportLayer().TransportFlow())
-}
-
-func BenchmarkListener_DecodePacket(b *testing.B) {
- var packetData = []byte{69, 0, 0, 134, 140, 133, 0, 0, 118, 17, 16, 79, 223, 5, 5, 5, 192, 168, 2, 224, 0, 53, 232, 163, 0, 114, 0, 0, 69, 42, 129, 128, 0, 1, 0, 3, 0, 0, 0, 0, 6, 115, 116, 97, 116, 105, 99, 7, 111, 115, 99, 104, 105, 110, 97, 3, 110, 101, 116, 0, 0, 1, 0, 1, 192, 12, 0, 5, 0, 1, 0, 0, 0, 1, 0, 25, 10, 115, 116, 97, 116, 105, 99, 45, 111, 115, 99, 2, 98, 48, 5, 97, 105, 99, 100, 110, 3, 99, 111, 109, 0, 192, 48, 0, 5, 0, 1, 0, 0, 0, 1, 0, 5, 2, 118, 109, 192, 62, 192, 85, 0, 1, 0, 1, 0, 0, 0, 1, 0, 4, 218, 28, 104, 157}
-
- var decodeOptions = gopacket.DecodeOptions{
- Lazy: true,
- NoCopy: true,
- //SkipDecodeRecovery: true,
- }
-
- for i := 0; i < b.N; i++ {
- var packet = gopacket.NewPacket(packetData, layers.LayerTypeIPv4, decodeOptions)
-
- var networkFlow = packet.NetworkLayer().NetworkFlow()
- var src = networkFlow.Src()
- var dest = networkFlow.Dst()
-
- _ = netpackets.IsLocalRawIPv4(src.Raw())
- _ = netpackets.IsLocalRawIPv4(dest.Raw())
-
- _ = src.String()
- _ = dest.String()
-
- _ = packet.Metadata().Length
-
- var transportFlow = packet.TransportLayer().TransportFlow()
- //_ = transportFlow.Src().String()
- //_ = transportFlow.Dst().String()
-
- _ = int(binary.BigEndian.Uint16(transportFlow.Src().Raw()))
- _ = int(binary.BigEndian.Uint16(transportFlow.Dst().Raw()))
- }
-}
diff --git a/EdgeNode/internal/utils/netpackets/packet_meta.go b/EdgeNode/internal/utils/netpackets/packet_meta.go
deleted file mode 100644
index 27856cf..0000000
--- a/EdgeNode/internal/utils/netpackets/packet_meta.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-//go:build plus && packet
-
-package netpackets
-
-type PacketMeta struct {
- LayerType LayerType
- SrcIP string
- SrcPort int
- DstIP string
- DstPort int
- Length int
-}
diff --git a/EdgeNode/internal/utils/netpackets/utils.go b/EdgeNode/internal/utils/netpackets/utils.go
deleted file mode 100644
index 6e25c3a..0000000
--- a/EdgeNode/internal/utils/netpackets/utils.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-
-package netpackets
-
-// IsLocalRawIPv4 使用原始IP数据判断是否为本地IPv4
-func IsLocalRawIPv4(ip []byte) bool {
- if len(ip) != 4 {
- return false
- }
- if ip[0] == 127 ||
- ip[0] == 10 ||
- (ip[0] == 172 && ip[1]&0xf0 == 16) ||
- (ip[0] == 192 && ip[1] == 168) {
- return true
- }
-
- return false
-}
diff --git a/EdgeNode/internal/utils/netpackets/utils_test.go b/EdgeNode/internal/utils/netpackets/utils_test.go
deleted file mode 100644
index 21b819a..0000000
--- a/EdgeNode/internal/utils/netpackets/utils_test.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
-
-package netpackets_test
-
-import (
- "github.com/TeaOSLab/EdgeNode/internal/utils/netpackets"
- "github.com/iwind/TeaGo/assert"
- "net"
- "testing"
-)
-
-func TestIsLocalRawIPv4(t *testing.T) {
- var a = assert.NewAssertion(t)
-
- a.IsTrue(netpackets.IsLocalRawIPv4(net.ParseIP("192.168.2.100").To4()))
- a.IsTrue(netpackets.IsLocalRawIPv4(net.ParseIP("127.0.0.1").To4()))
- a.IsTrue(netpackets.IsLocalRawIPv4(net.ParseIP("172.16.0.1").To4()))
- a.IsTrue(netpackets.IsLocalRawIPv4(net.ParseIP("10.0.0.1").To4()))
-
- a.IsFalse(netpackets.IsLocalRawIPv4(net.ParseIP("1.2.3.4").To4()))
-}
diff --git a/EdgeReporter/internal/const/const.go b/EdgeReporter/internal/const/const.go
index 5ca4e51..c2185c4 100644
--- a/EdgeReporter/internal/const/const.go
+++ b/EdgeReporter/internal/const/const.go
@@ -1,7 +1,7 @@
package teaconst
const (
- Version = "0.1.5"
+ Version = "1.5.0"
ProductName = "Edge Reporter"
ProcessName = "edge-reporter"
diff --git a/EdgeUser/internal/const/const.go b/EdgeUser/internal/const/const.go
index d085702..8ab7851 100644
--- a/EdgeUser/internal/const/const.go
+++ b/EdgeUser/internal/const/const.go
@@ -1,7 +1,7 @@
package teaconst
const (
- Version = "1.4.9" //1.3.8.2
+ Version = "1.5.0" //1.3.8.2
ProductName = "Edge User"
ProcessName = "edge-user"
diff --git a/deploy/deploy.sh b/deploy/deploy.sh
index 1b55a81..7e209f4 100644
--- a/deploy/deploy.sh
+++ b/deploy/deploy.sh
@@ -174,6 +174,8 @@ replace_files() {
# 替换 EdgeAdmin bin
if [ -d "$TEMP_DIR/edge-admin/bin" ]; then
log_info "替换 EdgeAdmin 可执行文件..."
+ rm -rf "$TARGET_DIR/bin"
+ mkdir -p "$TARGET_DIR/bin"
cp -r "$TEMP_DIR/edge-admin/bin"/* "$TARGET_DIR/bin/"
log_info "✅ EdgeAdmin bin 已更新"
fi
@@ -181,15 +183,9 @@ replace_files() {
# 替换 EdgeAdmin web(排除 tmp)
if [ -d "$TEMP_DIR/edge-admin/web" ]; then
log_info "替换 EdgeAdmin 前端文件..."
- if command -v rsync > /dev/null; then
- rsync -av --exclude='tmp' \
- "$TEMP_DIR/edge-admin/web/" "$TARGET_DIR/web/"
- else
- # 如果没有 rsync,使用 cp
- cp -r "$TEMP_DIR/edge-admin/web"/* "$TARGET_DIR/web/" 2>/dev/null || true
- rm -rf "$TARGET_DIR/web/tmp"/* 2>/dev/null || true
- fi
- # 清空 tmp 目录
+ rm -rf "$TARGET_DIR/web"
+ cp -r "$TEMP_DIR/edge-admin/web" "$TARGET_DIR/"
+ mkdir -p "$TARGET_DIR/web/tmp"
rm -rf "$TARGET_DIR/web/tmp"/* 2>/dev/null || true
log_info "✅ EdgeAdmin web 已更新"
fi
@@ -203,6 +199,7 @@ replace_files() {
# 替换 bin
if [ -d "$TEMP_DIR/edge-admin/edge-api/bin" ]; then
+ rm -rf "$TARGET_DIR/edge-api/bin"
mkdir -p "$TARGET_DIR/edge-api/bin"
cp -r "$TEMP_DIR/edge-admin/edge-api/bin"/* \
"$TARGET_DIR/edge-api/bin/" 2>/dev/null || true
@@ -211,6 +208,7 @@ replace_files() {
# 替换 deploy(节点安装包)
if [ -d "$TEMP_DIR/edge-admin/edge-api/deploy" ]; then
+ rm -rf "$TARGET_DIR/edge-api/deploy"
mkdir -p "$TARGET_DIR/edge-api/deploy"
cp -r "$TEMP_DIR/edge-admin/edge-api/deploy"/* \
"$TARGET_DIR/edge-api/deploy/" 2>/dev/null || true
@@ -219,6 +217,7 @@ replace_files() {
# 替换 installers(安装工具)
if [ -d "$TEMP_DIR/edge-admin/edge-api/installers" ]; then
+ rm -rf "$TARGET_DIR/edge-api/installers"
mkdir -p "$TARGET_DIR/edge-api/installers"
cp -r "$TEMP_DIR/edge-admin/edge-api/installers"/* \
"$TARGET_DIR/edge-api/installers/" 2>/dev/null || true
@@ -345,4 +344,3 @@ main() {
# 执行主函数
main
-
diff --git a/deploy/fluent-bit/packages/linux-amd64/fluent-bit-4.2.2-1.x86_64.rpm b/deploy/fluent-bit/packages/linux-amd64/fluent-bit-4.2.2-1.x86_64.rpm
deleted file mode 100644
index 6a2f7a4..0000000
Binary files a/deploy/fluent-bit/packages/linux-amd64/fluent-bit-4.2.2-1.x86_64.rpm and /dev/null differ
diff --git a/deploy/fluent-bit/packages/linux-amd64/fluent-bit_4.2.2_amd64.deb b/deploy/fluent-bit/packages/linux-amd64/fluent-bit_4.2.2_amd64.deb
deleted file mode 100644
index 9ef01a5..0000000
Binary files a/deploy/fluent-bit/packages/linux-amd64/fluent-bit_4.2.2_amd64.deb and /dev/null differ