diff --git a/EdgeAPI/build/build.sh b/EdgeAPI/build/build.sh index dade19e..9c58075 100644 --- a/EdgeAPI/build/build.sh +++ b/EdgeAPI/build/build.sh @@ -94,6 +94,32 @@ function build() { fi fi + # build edge-httpdns + HTTPDNS_ROOT=$ROOT"/../../EdgeHttpDNS" + if [ -d "$HTTPDNS_ROOT" ]; then + HTTPDNSNodeVersion=$(lookup-version "$ROOT""/../../EdgeHttpDNS/internal/const/const.go") + echo "building edge-httpdns v${HTTPDNSNodeVersion} ..." + EDGE_HTTPDNS_NODE_BUILD_SCRIPT=$ROOT"/../../EdgeHttpDNS/build/build.sh" + if [ ! -f "$EDGE_HTTPDNS_NODE_BUILD_SCRIPT" ]; then + echo "unable to find edge-httpdns build script 'EdgeHttpDNS/build/build.sh'" + exit + fi + cd "$ROOT""/../../EdgeHttpDNS/build" || exit + echo "==============================" + architects=("amd64") + #architects=("amd64" "arm64") + for arch in "${architects[@]}"; do + # always rebuild to avoid reusing stale zip when version number is unchanged + ./build.sh linux "$arch" + done + echo "==============================" + cd - || exit + + for arch in "${architects[@]}"; do + cp "$ROOT""/../../EdgeHttpDNS/dist/edge-httpdns-linux-${arch}-v${HTTPDNSNodeVersion}.zip" "$ROOT"/deploy/edge-httpdns-linux-"${arch}"-v"${HTTPDNSNodeVersion}".zip + done + fi + # build sql if [ $TAG = "plus" ]; then echo "building sql ..." diff --git a/EdgeAPI/internal/clickhouse/client.go b/EdgeAPI/internal/clickhouse/client.go index 96fe903..dba0895 100644 --- a/EdgeAPI/internal/clickhouse/client.go +++ b/EdgeAPI/internal/clickhouse/client.go @@ -1,6 +1,7 @@ package clickhouse import ( + "bytes" "context" "crypto/tls" "encoding/json" @@ -12,13 +13,11 @@ import ( "time" ) -// Client 通过 HTTP 接口执行只读查询(SELECT),返回 JSONEachRow 解析为 map 或结构体 type Client struct { cfg *Config httpCli *http.Client } -// NewClient 使用共享配置创建客户端 func NewClient() *Client { cfg := SharedConfig() transport := &http.Transport{} @@ -28,6 +27,7 @@ func NewClient() *Client { ServerName: cfg.TLSServerName, } } + return &Client{ cfg: cfg, httpCli: &http.Client{ @@ -37,21 +37,20 @@ func NewClient() *Client { } } -// IsConfigured 是否已配置 func (c *Client) IsConfigured() bool { return c.cfg != nil && c.cfg.IsConfigured() } -// Query 执行 SELECT,将每行 JSON 解析到 dest 切片;dest 元素类型需为 *struct 或 map func (c *Client) Query(ctx context.Context, query string, dest interface{}) error { if !c.IsConfigured() { return fmt.Errorf("clickhouse: not configured") } - // 强制 JSONEachRow 便于解析 + q := strings.TrimSpace(query) if !strings.HasSuffix(strings.ToUpper(q), "FORMAT JSONEACHROW") { query = q + " FORMAT JSONEachRow" } + u := c.buildURL(query) req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) if err != nil { @@ -60,28 +59,32 @@ func (c *Client) Query(ctx context.Context, query string, dest interface{}) erro if c.cfg.User != "" || c.cfg.Password != "" { req.SetBasicAuth(c.cfg.User, c.cfg.Password) } + resp, err := c.httpCli.Do(req) if err != nil { return err } defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("clickhouse HTTP %d: %s", resp.StatusCode, string(body)) } + dec := json.NewDecoder(resp.Body) return decodeRows(dec, dest) } -// QueryRow 执行仅返回一行的查询,将结果解析到 dest(*struct 或 *map) func (c *Client) QueryRow(ctx context.Context, query string, dest interface{}) error { if !c.IsConfigured() { return fmt.Errorf("clickhouse: not configured") } + q := strings.TrimSpace(query) if !strings.HasSuffix(strings.ToUpper(q), "FORMAT JSONEACHROW") { query = q + " FORMAT JSONEachRow" } + u := c.buildURL(query) req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) if err != nil { @@ -90,32 +93,109 @@ func (c *Client) QueryRow(ctx context.Context, query string, dest interface{}) e if c.cfg.User != "" || c.cfg.Password != "" { req.SetBasicAuth(c.cfg.User, c.cfg.Password) } + resp, err := c.httpCli.Do(req) if err != nil { return err } defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("clickhouse HTTP %d: %s", resp.StatusCode, string(body)) } + dec := json.NewDecoder(resp.Body) return decodeOneRow(dec, dest) } +func (c *Client) Execute(ctx context.Context, query string) error { + if !c.IsConfigured() { + return fmt.Errorf("clickhouse: not configured") + } + + u := c.buildURL(strings.TrimSpace(query)) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, u, nil) + if err != nil { + return err + } + if c.cfg.User != "" || c.cfg.Password != "" { + req.SetBasicAuth(c.cfg.User, c.cfg.Password) + } + + resp, err := c.httpCli.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + return fmt.Errorf("clickhouse HTTP %d: %s", resp.StatusCode, string(body)) + } + return nil +} + +func (c *Client) InsertJSONEachRow(ctx context.Context, insertSQL string, rows []map[string]interface{}) error { + if len(rows) == 0 { + return nil + } + if !c.IsConfigured() { + return fmt.Errorf("clickhouse: not configured") + } + + query := strings.TrimSpace(insertSQL) + if !strings.HasSuffix(strings.ToUpper(query), "FORMAT JSONEACHROW") { + query += " FORMAT JSONEachRow" + } + + var payload bytes.Buffer + for _, row := range rows { + if row == nil { + continue + } + data, err := json.Marshal(row) + if err != nil { + return err + } + payload.Write(data) + payload.WriteByte('\n') + } + + u := c.buildURL(query) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, u, &payload) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + if c.cfg.User != "" || c.cfg.Password != "" { + req.SetBasicAuth(c.cfg.User, c.cfg.Password) + } + + resp, err := c.httpCli.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + return fmt.Errorf("clickhouse HTTP %d: %s", resp.StatusCode, string(body)) + } + + return nil +} + func (c *Client) buildURL(query string) string { scheme := "http" if c.cfg != nil && strings.EqualFold(c.cfg.Scheme, "https") { scheme = "https" } - rawURL := fmt.Sprintf("%s://%s:%d/?query=%s&database=%s", + return fmt.Sprintf("%s://%s:%d/?query=%s&database=%s", scheme, c.cfg.Host, c.cfg.Port, url.QueryEscape(query), url.QueryEscape(c.cfg.Database)) - return rawURL } -// decodeRows 将 JSONEachRow 流解析到 slice;元素类型须为 *struct 或 *[]map[string]interface{} func decodeRows(dec *json.Decoder, dest interface{}) error { - // dest 应为 *[]*SomeStruct 或 *[]map[string]interface{} switch d := dest.(type) { case *[]map[string]interface{}: *d = (*d)[:0] @@ -130,7 +210,7 @@ func decodeRows(dec *json.Decoder, dest interface{}) error { *d = append(*d, row) } default: - return fmt.Errorf("clickhouse: unsupported dest type for Query (use *[]map[string]interface{} or implement decoder)") + return fmt.Errorf("clickhouse: unsupported dest type for Query (use *[]map[string]interface{})") } } diff --git a/EdgeAPI/internal/clickhouse/config.go b/EdgeAPI/internal/clickhouse/config.go index c2fe014..31add08 100644 --- a/EdgeAPI/internal/clickhouse/config.go +++ b/EdgeAPI/internal/clickhouse/config.go @@ -12,15 +12,15 @@ import ( ) const ( - envHost = "CLICKHOUSE_HOST" - envPort = "CLICKHOUSE_PORT" - envUser = "CLICKHOUSE_USER" - envPassword = "CLICKHOUSE_PASSWORD" - envDatabase = "CLICKHOUSE_DATABASE" - envScheme = "CLICKHOUSE_SCHEME" - defaultPort = 8443 - defaultDB = "default" - defaultScheme = "https" + envHost = "CLICKHOUSE_HOST" + envPort = "CLICKHOUSE_PORT" + envUser = "CLICKHOUSE_USER" + envPassword = "CLICKHOUSE_PASSWORD" + envDatabase = "CLICKHOUSE_DATABASE" + envScheme = "CLICKHOUSE_SCHEME" + defaultPort = 8443 + defaultDB = "default" + defaultScheme = "https" ) var ( diff --git a/EdgeAPI/internal/clickhouse/httpdns_access_logs_store.go b/EdgeAPI/internal/clickhouse/httpdns_access_logs_store.go new file mode 100644 index 0000000..14f76ce --- /dev/null +++ b/EdgeAPI/internal/clickhouse/httpdns_access_logs_store.go @@ -0,0 +1,279 @@ +package clickhouse + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + "strings" + + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" +) + +const httpDNSAccessLogsTable = "httpdns_access_logs_ingest" + +type HTTPDNSAccessLogRow struct { + RequestId string + ClusterId int64 + NodeId int64 + AppId string + AppName string + Domain string + QType string + ClientIP string + ClientRegion string + Carrier string + SDKVersion string + OS string + ResultIPs string + Status string + ErrorCode string + CostMs int32 + CreatedAt int64 + Day string + Summary string +} + +type HTTPDNSAccessLogListFilter struct { + Day string + ClusterId int64 + NodeId int64 + AppId string + Domain string + Status string + Keyword string + Offset int64 + Size int64 +} + +type HTTPDNSAccessLogsStore struct { + client *Client +} + +func NewHTTPDNSAccessLogsStore() *HTTPDNSAccessLogsStore { + return &HTTPDNSAccessLogsStore{client: NewClient()} +} + +func (s *HTTPDNSAccessLogsStore) Client() *Client { + return s.client +} + +func (s *HTTPDNSAccessLogsStore) Insert(ctx context.Context, logs []*pb.HTTPDNSAccessLog) error { + if len(logs) == 0 { + return nil + } + if !s.client.IsConfigured() { + return fmt.Errorf("clickhouse: not configured") + } + + rows := make([]map[string]interface{}, 0, len(logs)) + for _, item := range logs { + if item == nil { + continue + } + rows = append(rows, map[string]interface{}{ + "request_id": item.GetRequestId(), + "cluster_id": item.GetClusterId(), + "node_id": item.GetNodeId(), + "app_id": item.GetAppId(), + "app_name": item.GetAppName(), + "domain": item.GetDomain(), + "qtype": item.GetQtype(), + "client_ip": item.GetClientIP(), + "client_region": item.GetClientRegion(), + "carrier": item.GetCarrier(), + "sdk_version": item.GetSdkVersion(), + "os": item.GetOs(), + "result_ips": item.GetResultIPs(), + "status": item.GetStatus(), + "error_code": item.GetErrorCode(), + "cost_ms": item.GetCostMs(), + "created_at": item.GetCreatedAt(), + "day": item.GetDay(), + "summary": item.GetSummary(), + }) + } + + query := fmt.Sprintf("INSERT INTO %s (request_id, cluster_id, node_id, app_id, app_name, domain, qtype, client_ip, client_region, carrier, sdk_version, os, result_ips, status, error_code, cost_ms, created_at, day, summary)", + s.tableName()) + return s.client.InsertJSONEachRow(ctx, query, rows) +} + +func (s *HTTPDNSAccessLogsStore) Count(ctx context.Context, f HTTPDNSAccessLogListFilter) (int64, error) { + if !s.client.IsConfigured() { + return 0, fmt.Errorf("clickhouse: not configured") + } + + conditions := s.buildConditions(f) + query := fmt.Sprintf("SELECT count() AS count FROM %s", s.tableName()) + if len(conditions) > 0 { + query += " WHERE " + strings.Join(conditions, " AND ") + } + + row := map[string]interface{}{} + if err := s.client.QueryRow(ctx, query, &row); err != nil { + return 0, err + } + return toInt64(row["count"]), nil +} + +func (s *HTTPDNSAccessLogsStore) List(ctx context.Context, f HTTPDNSAccessLogListFilter) ([]*HTTPDNSAccessLogRow, error) { + if !s.client.IsConfigured() { + return nil, fmt.Errorf("clickhouse: not configured") + } + + size := f.Size + if size <= 0 { + size = 20 + } + if size > 1000 { + size = 1000 + } + offset := f.Offset + if offset < 0 { + offset = 0 + } + + conditions := s.buildConditions(f) + query := fmt.Sprintf("SELECT request_id, cluster_id, node_id, app_id, app_name, domain, qtype, client_ip, client_region, carrier, sdk_version, os, result_ips, status, error_code, cost_ms, created_at, day, summary FROM %s", + s.tableName()) + if len(conditions) > 0 { + query += " WHERE " + strings.Join(conditions, " AND ") + } + query += " ORDER BY created_at DESC, request_id DESC" + query += fmt.Sprintf(" LIMIT %d OFFSET %d", size, offset) + + rawRows := []map[string]interface{}{} + if err := s.client.Query(ctx, query, &rawRows); err != nil { + return nil, err + } + + result := make([]*HTTPDNSAccessLogRow, 0, len(rawRows)) + for _, row := range rawRows { + result = append(result, &HTTPDNSAccessLogRow{ + RequestId: toString(row["request_id"]), + ClusterId: toInt64(row["cluster_id"]), + NodeId: toInt64(row["node_id"]), + AppId: toString(row["app_id"]), + AppName: toString(row["app_name"]), + Domain: toString(row["domain"]), + QType: toString(row["qtype"]), + ClientIP: toString(row["client_ip"]), + ClientRegion: toString(row["client_region"]), + Carrier: toString(row["carrier"]), + SDKVersion: toString(row["sdk_version"]), + OS: toString(row["os"]), + ResultIPs: toString(row["result_ips"]), + Status: toString(row["status"]), + ErrorCode: toString(row["error_code"]), + CostMs: int32(toInt64(row["cost_ms"])), + CreatedAt: toInt64(row["created_at"]), + Day: toString(row["day"]), + Summary: toString(row["summary"]), + }) + } + return result, nil +} + +func HTTPDNSRowToPB(row *HTTPDNSAccessLogRow) *pb.HTTPDNSAccessLog { + if row == nil { + return nil + } + return &pb.HTTPDNSAccessLog{ + RequestId: row.RequestId, + ClusterId: row.ClusterId, + NodeId: row.NodeId, + AppId: row.AppId, + AppName: row.AppName, + Domain: row.Domain, + Qtype: row.QType, + ClientIP: row.ClientIP, + ClientRegion: row.ClientRegion, + Carrier: row.Carrier, + SdkVersion: row.SDKVersion, + Os: row.OS, + ResultIPs: row.ResultIPs, + Status: row.Status, + ErrorCode: row.ErrorCode, + CostMs: row.CostMs, + CreatedAt: row.CreatedAt, + Day: row.Day, + Summary: row.Summary, + } +} + +func (s *HTTPDNSAccessLogsStore) buildConditions(f HTTPDNSAccessLogListFilter) []string { + conditions := []string{} + if day := strings.TrimSpace(f.Day); day != "" { + conditions = append(conditions, "day = '"+escapeString(day)+"'") + } + if f.ClusterId > 0 { + conditions = append(conditions, "cluster_id = "+strconv.FormatInt(f.ClusterId, 10)) + } + if f.NodeId > 0 { + conditions = append(conditions, "node_id = "+strconv.FormatInt(f.NodeId, 10)) + } + if appID := strings.TrimSpace(f.AppId); appID != "" { + conditions = append(conditions, "app_id = '"+escapeString(appID)+"'") + } + if domain := strings.TrimSpace(f.Domain); domain != "" { + conditions = append(conditions, "domain = '"+escapeString(domain)+"'") + } + if status := strings.TrimSpace(f.Status); status != "" { + conditions = append(conditions, "status = '"+escapeString(status)+"'") + } + if keyword := strings.TrimSpace(f.Keyword); keyword != "" { + kw := escapeString(keyword) + conditions = append(conditions, "(summary LIKE '%"+kw+"%' OR app_name LIKE '%"+kw+"%' OR client_ip LIKE '%"+kw+"%' OR result_ips LIKE '%"+kw+"%')") + } + return conditions +} + +func (s *HTTPDNSAccessLogsStore) tableName() string { + if s.client != nil && s.client.cfg != nil && s.client.cfg.Database != "" && s.client.cfg.Database != "default" { + return quoteIdent(s.client.cfg.Database) + "." + quoteIdent(httpDNSAccessLogsTable) + } + return quoteIdent(httpDNSAccessLogsTable) +} + +func toString(value interface{}) string { + if value == nil { + return "" + } + switch v := value.(type) { + case string: + return v + case json.Number: + return v.String() + default: + return fmt.Sprintf("%v", v) + } +} + +func toInt64(value interface{}) int64 { + if value == nil { + return 0 + } + switch v := value.(type) { + case int: + return int64(v) + case int32: + return int64(v) + case int64: + return v + case uint32: + return int64(v) + case uint64: + return int64(v) + case float64: + return int64(v) + case json.Number: + n, _ := v.Int64() + return n + case string: + n, _ := strconv.ParseInt(v, 10, 64) + return n + default: + return 0 + } +} diff --git a/EdgeAPI/internal/clickhouse/logs_ingest_store.go b/EdgeAPI/internal/clickhouse/logs_ingest_store.go index 4cbc965..84f7a56 100644 --- a/EdgeAPI/internal/clickhouse/logs_ingest_store.go +++ b/EdgeAPI/internal/clickhouse/logs_ingest_store.go @@ -351,8 +351,8 @@ func RowToPB(r *LogsIngestRow) *pb.HTTPAccessLog { RemoteAddr: r.IP, RequestMethod: r.Method, RequestPath: r.Path, - RequestURI: r.Path, // 前端使用 requestURI 显示完整路径 - Scheme: "http", // 默认 http,日志中未存储实际值 + RequestURI: r.Path, // 前端使用 requestURI 显示完整路径 + Scheme: "http", // 默认 http,日志中未存储实际值 Proto: "HTTP/1.1", // 默认值,日志中未存储实际值 Status: int32(r.Status), RequestLength: int64(r.BytesIn), diff --git a/EdgeAPI/internal/const/const.go b/EdgeAPI/internal/const/const.go index 89f1e42..14d8d93 100644 --- a/EdgeAPI/internal/const/const.go +++ b/EdgeAPI/internal/const/const.go @@ -1,7 +1,7 @@ package teaconst const ( - Version = "1.4.7" //1.3.9 + Version = "1.4.8" //1.3.9 ProductName = "Edge API" ProcessName = "edge-api" @@ -17,6 +17,6 @@ const ( // 其他节点版本号,用来检测是否有需要升级的节点 - NodeVersion = "1.4.7" //1.3.8.2 + NodeVersion = "1.4.8" //1.3.8.2 ) diff --git a/EdgeAPI/internal/const/const_plus.go b/EdgeAPI/internal/const/const_plus.go index 44ea4f5..56e5324 100644 --- a/EdgeAPI/internal/const/const_plus.go +++ b/EdgeAPI/internal/const/const_plus.go @@ -4,8 +4,8 @@ package teaconst const ( - DNSNodeVersion = "1.4.7" //1.3.8.2 - UserNodeVersion = "1.4.7" //1.3.8.2 + DNSNodeVersion = "1.4.8" //1.3.8.2 + UserNodeVersion = "1.4.8" //1.3.8.2 ReportNodeVersion = "0.1.5" DefaultMaxNodes int32 = 50 diff --git a/EdgeAPI/internal/db/models/httpdns_access_log_dao.go b/EdgeAPI/internal/db/models/httpdns_access_log_dao.go new file mode 100644 index 0000000..9bcbf17 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_access_log_dao.go @@ -0,0 +1,101 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" +) + +type HTTPDNSAccessLogDAO dbs.DAO + +func NewHTTPDNSAccessLogDAO() *HTTPDNSAccessLogDAO { + return dbs.NewDAO(&HTTPDNSAccessLogDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSAccessLogs", + Model: new(HTTPDNSAccessLog), + PkName: "id", + }, + }).(*HTTPDNSAccessLogDAO) +} + +var SharedHTTPDNSAccessLogDAO *HTTPDNSAccessLogDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSAccessLogDAO = NewHTTPDNSAccessLogDAO() + }) +} + +func (this *HTTPDNSAccessLogDAO) CreateLog(tx *dbs.Tx, log *HTTPDNSAccessLog) error { + var op = NewHTTPDNSAccessLogOperator() + op.RequestId = log.RequestId + op.ClusterId = log.ClusterId + op.NodeId = log.NodeId + op.AppId = log.AppId + op.AppName = log.AppName + op.Domain = log.Domain + op.QType = log.QType + op.ClientIP = log.ClientIP + op.ClientRegion = log.ClientRegion + op.Carrier = log.Carrier + op.SDKVersion = log.SDKVersion + op.OS = log.OS + op.ResultIPs = log.ResultIPs + op.Status = log.Status + op.ErrorCode = log.ErrorCode + op.CostMs = log.CostMs + op.CreatedAt = log.CreatedAt + op.Day = log.Day + op.Summary = log.Summary + return this.Save(tx, op) +} + +func (this *HTTPDNSAccessLogDAO) BuildListQuery(tx *dbs.Tx, day string, clusterId int64, nodeId int64, appId string, domain string, status string, keyword string) *dbs.Query { + query := this.Query(tx).DescPk() + if len(day) > 0 { + query = query.Attr("day", day) + } + if clusterId > 0 { + query = query.Attr("clusterId", clusterId) + } + if nodeId > 0 { + query = query.Attr("nodeId", nodeId) + } + if len(appId) > 0 { + query = query.Attr("appId", appId) + } + if len(domain) > 0 { + query = query.Attr("domain", domain) + } + if len(status) > 0 { + query = query.Attr("status", status) + } + if len(keyword) > 0 { + query = query.Where("(summary LIKE :kw OR appName LIKE :kw OR clientIP LIKE :kw OR resultIPs LIKE :kw)").Param("kw", "%"+keyword+"%") + } + return query +} + +func (this *HTTPDNSAccessLogDAO) CountLogs(tx *dbs.Tx, day string, clusterId int64, nodeId int64, appId string, domain string, status string, keyword string) (int64, error) { + return this.BuildListQuery(tx, day, clusterId, nodeId, appId, domain, status, keyword).Count() +} + +func (this *HTTPDNSAccessLogDAO) ListLogs(tx *dbs.Tx, day string, clusterId int64, nodeId int64, appId string, domain string, status string, keyword string, offset int64, size int64) (result []*HTTPDNSAccessLog, err error) { + _, err = this.BuildListQuery(tx, day, clusterId, nodeId, appId, domain, status, keyword). + Offset(offset). + Limit(size). + Slice(&result). + FindAll() + return +} + +func (this *HTTPDNSAccessLogDAO) DeleteLogsWithAppId(tx *dbs.Tx, appId string) error { + if len(appId) == 0 { + return nil + } + _, err := this.Query(tx). + Attr("appId", appId). + Delete() + return err +} diff --git a/EdgeAPI/internal/db/models/httpdns_access_log_model.go b/EdgeAPI/internal/db/models/httpdns_access_log_model.go new file mode 100644 index 0000000..0c8da61 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_access_log_model.go @@ -0,0 +1,52 @@ +package models + +// HTTPDNSAccessLog 访问日志 +type HTTPDNSAccessLog struct { + Id uint64 `field:"id"` // ID + RequestId string `field:"requestId"` // 请求ID + ClusterId uint32 `field:"clusterId"` // 集群ID + NodeId uint32 `field:"nodeId"` // 节点ID + AppId string `field:"appId"` // AppID + AppName string `field:"appName"` // 应用名 + Domain string `field:"domain"` // 域名 + QType string `field:"qtype"` // 查询类型 + ClientIP string `field:"clientIP"` // 客户端IP + ClientRegion string `field:"clientRegion"` // 客户端区域 + Carrier string `field:"carrier"` // 运营商 + SDKVersion string `field:"sdkVersion"` // SDK版本 + OS string `field:"os"` // 系统 + ResultIPs string `field:"resultIPs"` // 结果IP + Status string `field:"status"` // 状态 + ErrorCode string `field:"errorCode"` // 错误码 + CostMs int32 `field:"costMs"` // 耗时 + CreatedAt uint64 `field:"createdAt"` // 创建时间 + Day string `field:"day"` // YYYYMMDD + Summary string `field:"summary"` // 概要 +} + +type HTTPDNSAccessLogOperator struct { + Id any // ID + RequestId any // 请求ID + ClusterId any // 集群ID + NodeId any // 节点ID + AppId any // AppID + AppName any // 应用名 + Domain any // 域名 + QType any // 查询类型 + ClientIP any // 客户端IP + ClientRegion any // 客户端区域 + Carrier any // 运营商 + SDKVersion any // SDK版本 + OS any // 系统 + ResultIPs any // 结果IP + Status any // 状态 + ErrorCode any // 错误码 + CostMs any // 耗时 + CreatedAt any // 创建时间 + Day any // YYYYMMDD + Summary any // 概要 +} + +func NewHTTPDNSAccessLogOperator() *HTTPDNSAccessLogOperator { + return &HTTPDNSAccessLogOperator{} +} diff --git a/EdgeAPI/internal/db/models/httpdns_app_dao.go b/EdgeAPI/internal/db/models/httpdns_app_dao.go new file mode 100644 index 0000000..0af29b7 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_app_dao.go @@ -0,0 +1,128 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/types" + "time" +) + +const ( + HTTPDNSAppStateEnabled = 1 + HTTPDNSAppStateDisabled = 0 + HTTPDNSSNIModeFixedHide = "fixed_hide" +) + +type HTTPDNSAppDAO dbs.DAO + +func NewHTTPDNSAppDAO() *HTTPDNSAppDAO { + return dbs.NewDAO(&HTTPDNSAppDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSApps", + Model: new(HTTPDNSApp), + PkName: "id", + }, + }).(*HTTPDNSAppDAO) +} + +var SharedHTTPDNSAppDAO *HTTPDNSAppDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSAppDAO = NewHTTPDNSAppDAO() + }) +} + +func (this *HTTPDNSAppDAO) CreateApp(tx *dbs.Tx, name string, appId string, primaryClusterId int64, backupClusterId int64, isOn bool, userId int64) (int64, error) { + var op = NewHTTPDNSAppOperator() + op.Name = name + op.AppId = appId + op.PrimaryClusterId = primaryClusterId + op.BackupClusterId = backupClusterId + op.IsOn = isOn + op.UserId = userId + op.SNIMode = HTTPDNSSNIModeFixedHide + op.CreatedAt = time.Now().Unix() + op.UpdatedAt = time.Now().Unix() + op.State = HTTPDNSAppStateEnabled + err := this.Save(tx, op) + if err != nil { + return 0, err + } + return types.Int64(op.Id), nil +} + +func (this *HTTPDNSAppDAO) UpdateApp(tx *dbs.Tx, appDbId int64, name string, primaryClusterId int64, backupClusterId int64, isOn bool, userId int64) error { + var op = NewHTTPDNSAppOperator() + op.Id = appDbId + op.Name = name + op.PrimaryClusterId = primaryClusterId + op.BackupClusterId = backupClusterId + op.IsOn = isOn + op.UserId = userId + op.UpdatedAt = time.Now().Unix() + return this.Save(tx, op) +} + +func (this *HTTPDNSAppDAO) DisableApp(tx *dbs.Tx, appDbId int64) error { + _, err := this.Query(tx). + Pk(appDbId). + Set("state", HTTPDNSAppStateDisabled). + Update() + return err +} + +func (this *HTTPDNSAppDAO) FindEnabledApp(tx *dbs.Tx, appDbId int64) (*HTTPDNSApp, error) { + one, err := this.Query(tx). + Pk(appDbId). + State(HTTPDNSAppStateEnabled). + Find() + if one == nil { + return nil, err + } + return one.(*HTTPDNSApp), nil +} + +func (this *HTTPDNSAppDAO) FindEnabledAppWithAppId(tx *dbs.Tx, appId string) (*HTTPDNSApp, error) { + one, err := this.Query(tx). + State(HTTPDNSAppStateEnabled). + Attr("appId", appId). + Find() + if one == nil { + return nil, err + } + return one.(*HTTPDNSApp), nil +} + +func (this *HTTPDNSAppDAO) ListEnabledApps(tx *dbs.Tx, offset int64, size int64, keyword string) (result []*HTTPDNSApp, err error) { + query := this.Query(tx). + State(HTTPDNSAppStateEnabled). + AscPk() + if len(keyword) > 0 { + query = query.Where("(name LIKE :kw OR appId LIKE :kw)").Param("kw", "%"+keyword+"%") + } + if size > 0 { + query = query.Offset(offset).Limit(size) + } + _, err = query.Slice(&result).FindAll() + return +} + +func (this *HTTPDNSAppDAO) CountEnabledApps(tx *dbs.Tx, keyword string) (int64, error) { + query := this.Query(tx).State(HTTPDNSAppStateEnabled) + if len(keyword) > 0 { + query = query.Where("(name LIKE :kw OR appId LIKE :kw)").Param("kw", "%"+keyword+"%") + } + return query.Count() +} + +func (this *HTTPDNSAppDAO) FindAllEnabledApps(tx *dbs.Tx) (result []*HTTPDNSApp, err error) { + _, err = this.Query(tx). + State(HTTPDNSAppStateEnabled). + AscPk(). + Slice(&result). + FindAll() + return +} diff --git a/EdgeAPI/internal/db/models/httpdns_app_model.go b/EdgeAPI/internal/db/models/httpdns_app_model.go new file mode 100644 index 0000000..113fe9f --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_app_model.go @@ -0,0 +1,36 @@ +package models + +// HTTPDNSApp maps to edgeHTTPDNSApps. +type HTTPDNSApp struct { + Id uint32 `field:"id"` // id + Name string `field:"name"` // app name + AppId string `field:"appId"` // external app id + IsOn bool `field:"isOn"` // enabled + PrimaryClusterId uint32 `field:"primaryClusterId"` // primary cluster id + BackupClusterId uint32 `field:"backupClusterId"` // backup cluster id + SNIMode string `field:"sniMode"` // sni mode + UserId int64 `field:"userId"` // owner user id + CreatedAt uint64 `field:"createdAt"` // created unix ts + UpdatedAt uint64 `field:"updatedAt"` // updated unix ts + State uint8 `field:"state"` // state +} + +// HTTPDNSAppOperator is used by DAO save/update. +type HTTPDNSAppOperator struct { + Id any // id + Name any // app name + AppId any // external app id + IsOn any // enabled + PrimaryClusterId any // primary cluster id + BackupClusterId any // backup cluster id + SNIMode any // sni mode + UserId any // owner user id + CreatedAt any // created unix ts + UpdatedAt any // updated unix ts + State any // state +} + +func NewHTTPDNSAppOperator() *HTTPDNSAppOperator { + return &HTTPDNSAppOperator{} +} + diff --git a/EdgeAPI/internal/db/models/httpdns_app_secret_dao.go b/EdgeAPI/internal/db/models/httpdns_app_secret_dao.go new file mode 100644 index 0000000..b2d1934 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_app_secret_dao.go @@ -0,0 +1,125 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/rands" + "github.com/iwind/TeaGo/types" + "time" +) + +const ( + HTTPDNSAppSecretStateEnabled = 1 + HTTPDNSAppSecretStateDisabled = 0 +) + +type HTTPDNSAppSecretDAO dbs.DAO + +func NewHTTPDNSAppSecretDAO() *HTTPDNSAppSecretDAO { + return dbs.NewDAO(&HTTPDNSAppSecretDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSAppSecrets", + Model: new(HTTPDNSAppSecret), + PkName: "id", + }, + }).(*HTTPDNSAppSecretDAO) +} + +var SharedHTTPDNSAppSecretDAO *HTTPDNSAppSecretDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSAppSecretDAO = NewHTTPDNSAppSecretDAO() + }) +} + +func (this *HTTPDNSAppSecretDAO) InitAppSecret(tx *dbs.Tx, appDbId int64, signEnabled bool) (string, uint64, error) { + signSecret := "ss_" + rands.HexString(12) + now := uint64(time.Now().Unix()) + var op = NewHTTPDNSAppSecretOperator() + op.AppId = appDbId + op.SignEnabled = signEnabled + op.SignSecret = signSecret + op.SignUpdatedAt = now + op.UpdatedAt = now + op.State = HTTPDNSAppSecretStateEnabled + err := this.Save(tx, op) + return signSecret, now, err +} + +func (this *HTTPDNSAppSecretDAO) FindEnabledAppSecret(tx *dbs.Tx, appDbId int64) (*HTTPDNSAppSecret, error) { + one, err := this.Query(tx). + Attr("appId", appDbId). + State(HTTPDNSAppSecretStateEnabled). + Find() + if one == nil { + return nil, err + } + return one.(*HTTPDNSAppSecret), nil +} + +func (this *HTTPDNSAppSecretDAO) UpdateSignEnabled(tx *dbs.Tx, appDbId int64, signEnabled bool) error { + _, err := this.Query(tx). + Attr("appId", appDbId). + State(HTTPDNSAppSecretStateEnabled). + Set("signEnabled", signEnabled). + Set("updatedAt", time.Now().Unix()). + Update() + return err +} + +func (this *HTTPDNSAppSecretDAO) ResetSignSecret(tx *dbs.Tx, appDbId int64) (string, int64, error) { + signSecret := "ss_" + rands.HexString(12) + now := time.Now().Unix() + _, err := this.Query(tx). + Attr("appId", appDbId). + State(HTTPDNSAppSecretStateEnabled). + Set("signSecret", signSecret). + Set("signUpdatedAt", now). + Set("updatedAt", now). + Update() + if err != nil { + return "", 0, err + } + return signSecret, now, nil +} + +func (this *HTTPDNSAppSecretDAO) FindSignEnabled(tx *dbs.Tx, appDbId int64) (bool, error) { + one, err := this.FindEnabledAppSecret(tx, appDbId) + if err != nil || one == nil { + return false, err + } + return one.SignEnabled, nil +} + +func (this *HTTPDNSAppSecretDAO) FindSignSecretWithAppDbId(tx *dbs.Tx, appDbId int64) (string, error) { + return this.Query(tx). + Attr("appId", appDbId). + State(HTTPDNSAppSecretStateEnabled). + Result("signSecret"). + FindStringCol("") +} + +func (this *HTTPDNSAppSecretDAO) FindSignUpdatedAt(tx *dbs.Tx, appDbId int64) (int64, error) { + col, err := this.Query(tx). + Attr("appId", appDbId). + State(HTTPDNSAppSecretStateEnabled). + Result("signUpdatedAt"). + FindCol(nil) + if err != nil { + return 0, err + } + return types.Int64(col), nil +} + +func (this *HTTPDNSAppSecretDAO) DisableAppSecret(tx *dbs.Tx, appDbId int64) error { + _, err := this.Query(tx). + Attr("appId", appDbId). + State(HTTPDNSAppSecretStateEnabled). + Set("state", HTTPDNSAppSecretStateDisabled). + Set("updatedAt", time.Now().Unix()). + Update() + return err +} diff --git a/EdgeAPI/internal/db/models/httpdns_app_secret_model.go b/EdgeAPI/internal/db/models/httpdns_app_secret_model.go new file mode 100644 index 0000000..92563a7 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_app_secret_model.go @@ -0,0 +1,26 @@ +package models + +// HTTPDNSAppSecret 应用验签密钥配置 +type HTTPDNSAppSecret struct { + Id uint32 `field:"id"` // ID + AppId uint32 `field:"appId"` // 应用DB ID + SignEnabled bool `field:"signEnabled"` // 是否启用验签 + SignSecret string `field:"signSecret"` // 验签密钥(当前先明文存储) + SignUpdatedAt uint64 `field:"signUpdatedAt"` // 验签密钥更新时间 + UpdatedAt uint64 `field:"updatedAt"` // 修改时间 + State uint8 `field:"state"` // 记录状态 +} + +type HTTPDNSAppSecretOperator struct { + Id any // ID + AppId any // 应用DB ID + SignEnabled any // 是否启用验签 + SignSecret any // 验签密钥 + SignUpdatedAt any // 验签密钥更新时间 + UpdatedAt any // 修改时间 + State any // 记录状态 +} + +func NewHTTPDNSAppSecretOperator() *HTTPDNSAppSecretOperator { + return &HTTPDNSAppSecretOperator{} +} diff --git a/EdgeAPI/internal/db/models/httpdns_cluster_dao.go b/EdgeAPI/internal/db/models/httpdns_cluster_dao.go new file mode 100644 index 0000000..872b5d0 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_cluster_dao.go @@ -0,0 +1,169 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/types" + "time" +) + +const ( + HTTPDNSClusterStateEnabled = 1 + HTTPDNSClusterStateDisabled = 0 +) + +type HTTPDNSClusterDAO dbs.DAO + +func NewHTTPDNSClusterDAO() *HTTPDNSClusterDAO { + return dbs.NewDAO(&HTTPDNSClusterDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSClusters", + Model: new(HTTPDNSCluster), + PkName: "id", + }, + }).(*HTTPDNSClusterDAO) +} + +var SharedHTTPDNSClusterDAO *HTTPDNSClusterDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSClusterDAO = NewHTTPDNSClusterDAO() + }) +} + +func (this *HTTPDNSClusterDAO) CreateCluster(tx *dbs.Tx, name string, serviceDomain string, defaultTTL int32, fallbackTimeoutMs int32, installDir string, tlsPolicyJSON []byte, isOn bool, isDefault bool) (int64, error) { + if isDefault { + err := this.Query(tx). + State(HTTPDNSClusterStateEnabled). + Set("isDefault", false). + UpdateQuickly() + if err != nil { + return 0, err + } + } + + var op = NewHTTPDNSClusterOperator() + op.Name = name + op.ServiceDomain = serviceDomain + op.DefaultTTL = defaultTTL + op.FallbackTimeoutMs = fallbackTimeoutMs + op.InstallDir = installDir + op.IsOn = isOn + op.IsDefault = isDefault + op.CreatedAt = time.Now().Unix() + op.UpdatedAt = time.Now().Unix() + op.State = HTTPDNSClusterStateEnabled + if len(tlsPolicyJSON) > 0 { + op.TLSPolicy = tlsPolicyJSON + } + err := this.Save(tx, op) + if err != nil { + return 0, err + } + return types.Int64(op.Id), nil +} + +func (this *HTTPDNSClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, serviceDomain string, defaultTTL int32, fallbackTimeoutMs int32, installDir string, tlsPolicyJSON []byte, isOn bool, isDefault bool) error { + if isDefault { + err := this.Query(tx). + State(HTTPDNSClusterStateEnabled). + Neq("id", clusterId). + Set("isDefault", false). + UpdateQuickly() + if err != nil { + return err + } + } + + var op = NewHTTPDNSClusterOperator() + op.Id = clusterId + op.Name = name + op.ServiceDomain = serviceDomain + op.DefaultTTL = defaultTTL + op.FallbackTimeoutMs = fallbackTimeoutMs + op.InstallDir = installDir + op.IsOn = isOn + op.IsDefault = isDefault + op.UpdatedAt = time.Now().Unix() + if len(tlsPolicyJSON) > 0 { + op.TLSPolicy = tlsPolicyJSON + } + return this.Save(tx, op) +} + +func (this *HTTPDNSClusterDAO) DisableCluster(tx *dbs.Tx, clusterId int64) error { + _, err := this.Query(tx). + Pk(clusterId). + Set("state", HTTPDNSClusterStateDisabled). + Update() + return err +} + +func (this *HTTPDNSClusterDAO) FindEnabledCluster(tx *dbs.Tx, clusterId int64) (*HTTPDNSCluster, error) { + one, err := this.Query(tx). + Pk(clusterId). + State(HTTPDNSClusterStateEnabled). + Find() + if one == nil { + return nil, err + } + return one.(*HTTPDNSCluster), nil +} + +func (this *HTTPDNSClusterDAO) FindEnabledClusterName(tx *dbs.Tx, clusterId int64) (string, error) { + return this.Query(tx). + Pk(clusterId). + State(HTTPDNSClusterStateEnabled). + Result("name"). + FindStringCol("") +} + +func (this *HTTPDNSClusterDAO) ListEnabledClusters(tx *dbs.Tx, offset int64, size int64, keyword string) (result []*HTTPDNSCluster, err error) { + query := this.Query(tx). + State(HTTPDNSClusterStateEnabled). + AscPk() + if len(keyword) > 0 { + query = query.Where("(name LIKE :kw OR serviceDomain LIKE :kw)").Param("kw", "%"+keyword+"%") + } + if size > 0 { + query = query.Offset(offset).Limit(size) + } + _, err = query.Slice(&result).FindAll() + return +} + +func (this *HTTPDNSClusterDAO) CountEnabledClusters(tx *dbs.Tx, keyword string) (int64, error) { + query := this.Query(tx).State(HTTPDNSClusterStateEnabled) + if len(keyword) > 0 { + query = query.Where("(name LIKE :kw OR serviceDomain LIKE :kw)").Param("kw", "%"+keyword+"%") + } + return query.Count() +} + +func (this *HTTPDNSClusterDAO) FindAllEnabledClusters(tx *dbs.Tx) (result []*HTTPDNSCluster, err error) { + _, err = this.Query(tx). + State(HTTPDNSClusterStateEnabled). + AscPk(). + Slice(&result). + FindAll() + return +} + +func (this *HTTPDNSClusterDAO) UpdateDefaultCluster(tx *dbs.Tx, clusterId int64) error { + err := this.Query(tx). + State(HTTPDNSClusterStateEnabled). + Set("isDefault", false). + UpdateQuickly() + if err != nil { + return err + } + _, err = this.Query(tx). + Pk(clusterId). + State(HTTPDNSClusterStateEnabled). + Set("isDefault", true). + Update() + return err +} diff --git a/EdgeAPI/internal/db/models/httpdns_cluster_model.go b/EdgeAPI/internal/db/models/httpdns_cluster_model.go new file mode 100644 index 0000000..00aeaf1 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_cluster_model.go @@ -0,0 +1,38 @@ +package models + +import "github.com/iwind/TeaGo/dbs" + +// HTTPDNSCluster HTTPDNS集群 +type HTTPDNSCluster struct { + Id uint32 `field:"id"` // ID + Name string `field:"name"` // 集群名称 + IsOn bool `field:"isOn"` // 是否启用 + IsDefault bool `field:"isDefault"` // 默认集群 + ServiceDomain string `field:"serviceDomain"` // 服务域名 + DefaultTTL int32 `field:"defaultTTL"` // 默认TTL + FallbackTimeoutMs int32 `field:"fallbackTimeoutMs"` // 降级超时 + InstallDir string `field:"installDir"` // 安装目录 + TLSPolicy dbs.JSON `field:"tlsPolicy"` // TLS策略 + CreatedAt uint64 `field:"createdAt"` // 创建时间 + UpdatedAt uint64 `field:"updatedAt"` // 修改时间 + State uint8 `field:"state"` // 记录状态 +} + +type HTTPDNSClusterOperator struct { + Id any // ID + Name any // 集群名称 + IsOn any // 是否启用 + IsDefault any // 默认集群 + ServiceDomain any // 服务域名 + DefaultTTL any // 默认TTL + FallbackTimeoutMs any // 降级超时 + InstallDir any // 安装目录 + TLSPolicy any // TLS策略 + CreatedAt any // 创建时间 + UpdatedAt any // 修改时间 + State any // 记录状态 +} + +func NewHTTPDNSClusterOperator() *HTTPDNSClusterOperator { + return &HTTPDNSClusterOperator{} +} diff --git a/EdgeAPI/internal/db/models/httpdns_custom_rule_dao.go b/EdgeAPI/internal/db/models/httpdns_custom_rule_dao.go new file mode 100644 index 0000000..0df5629 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_custom_rule_dao.go @@ -0,0 +1,143 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/types" + "time" +) + +const ( + HTTPDNSCustomRuleStateEnabled = 1 + HTTPDNSCustomRuleStateDisabled = 0 +) + +type HTTPDNSCustomRuleDAO dbs.DAO + +func NewHTTPDNSCustomRuleDAO() *HTTPDNSCustomRuleDAO { + return dbs.NewDAO(&HTTPDNSCustomRuleDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSCustomRules", + Model: new(HTTPDNSCustomRule), + PkName: "id", + }, + }).(*HTTPDNSCustomRuleDAO) +} + +var SharedHTTPDNSCustomRuleDAO *HTTPDNSCustomRuleDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSCustomRuleDAO = NewHTTPDNSCustomRuleDAO() + }) +} + +func (this *HTTPDNSCustomRuleDAO) CreateRule(tx *dbs.Tx, rule *HTTPDNSCustomRule) (int64, error) { + var op = NewHTTPDNSCustomRuleOperator() + op.AppId = rule.AppId + op.DomainId = rule.DomainId + op.RuleName = rule.RuleName + op.LineScope = rule.LineScope + op.LineCarrier = rule.LineCarrier + op.LineRegion = rule.LineRegion + op.LineProvince = rule.LineProvince + op.LineContinent = rule.LineContinent + op.LineCountry = rule.LineCountry + op.TTL = rule.TTL + op.IsOn = rule.IsOn + op.Priority = rule.Priority + op.UpdatedAt = time.Now().Unix() + op.State = HTTPDNSCustomRuleStateEnabled + err := this.Save(tx, op) + if err != nil { + return 0, err + } + return types.Int64(op.Id), nil +} + +func (this *HTTPDNSCustomRuleDAO) UpdateRule(tx *dbs.Tx, rule *HTTPDNSCustomRule) error { + var op = NewHTTPDNSCustomRuleOperator() + op.Id = rule.Id + op.RuleName = rule.RuleName + op.LineScope = rule.LineScope + op.LineCarrier = rule.LineCarrier + op.LineRegion = rule.LineRegion + op.LineProvince = rule.LineProvince + op.LineContinent = rule.LineContinent + op.LineCountry = rule.LineCountry + op.TTL = rule.TTL + op.IsOn = rule.IsOn + op.Priority = rule.Priority + op.UpdatedAt = time.Now().Unix() + return this.Save(tx, op) +} + +func (this *HTTPDNSCustomRuleDAO) DisableRule(tx *dbs.Tx, ruleId int64) error { + _, err := this.Query(tx). + Pk(ruleId). + Set("state", HTTPDNSCustomRuleStateDisabled). + Update() + return err +} + +func (this *HTTPDNSCustomRuleDAO) DisableRulesWithAppId(tx *dbs.Tx, appDbId int64) error { + _, err := this.Query(tx). + Attr("appId", appDbId). + State(HTTPDNSCustomRuleStateEnabled). + Set("state", HTTPDNSCustomRuleStateDisabled). + Set("updatedAt", time.Now().Unix()). + Update() + return err +} + +func (this *HTTPDNSCustomRuleDAO) UpdateRuleStatus(tx *dbs.Tx, ruleId int64, isOn bool) error { + _, err := this.Query(tx). + Pk(ruleId). + State(HTTPDNSCustomRuleStateEnabled). + Set("isOn", isOn). + Set("updatedAt", time.Now().Unix()). + Update() + return err +} + +func (this *HTTPDNSCustomRuleDAO) FindEnabledRule(tx *dbs.Tx, ruleId int64) (*HTTPDNSCustomRule, error) { + one, err := this.Query(tx). + Pk(ruleId). + State(HTTPDNSCustomRuleStateEnabled). + Find() + if one == nil { + return nil, err + } + return one.(*HTTPDNSCustomRule), nil +} + +func (this *HTTPDNSCustomRuleDAO) ListEnabledRulesWithDomainId(tx *dbs.Tx, domainId int64) (result []*HTTPDNSCustomRule, err error) { + _, err = this.Query(tx). + State(HTTPDNSCustomRuleStateEnabled). + Attr("domainId", domainId). + Asc("priority"). + AscPk(). + Slice(&result). + FindAll() + return +} + +func (this *HTTPDNSCustomRuleDAO) ListEnabledRulesWithAppId(tx *dbs.Tx, appDbId int64) (result []*HTTPDNSCustomRule, err error) { + _, err = this.Query(tx). + State(HTTPDNSCustomRuleStateEnabled). + Attr("appId", appDbId). + Asc("priority"). + AscPk(). + Slice(&result). + FindAll() + return +} + +func (this *HTTPDNSCustomRuleDAO) CountEnabledRulesWithDomainId(tx *dbs.Tx, domainId int64) (int64, error) { + return this.Query(tx). + State(HTTPDNSCustomRuleStateEnabled). + Attr("domainId", domainId). + Count() +} diff --git a/EdgeAPI/internal/db/models/httpdns_custom_rule_model.go b/EdgeAPI/internal/db/models/httpdns_custom_rule_model.go new file mode 100644 index 0000000..8120152 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_custom_rule_model.go @@ -0,0 +1,42 @@ +package models + +// HTTPDNSCustomRule 自定义解析规则 +type HTTPDNSCustomRule struct { + Id uint32 `field:"id"` // ID + AppId uint32 `field:"appId"` // 应用DB ID + DomainId uint32 `field:"domainId"` // 域名ID + RuleName string `field:"ruleName"` // 规则名称 + LineScope string `field:"lineScope"` // 线路范围 + LineCarrier string `field:"lineCarrier"` // 运营商 + LineRegion string `field:"lineRegion"` // 区域 + LineProvince string `field:"lineProvince"` // 省份 + LineContinent string `field:"lineContinent"` // 大洲 + LineCountry string `field:"lineCountry"` // 国家 + TTL int32 `field:"ttl"` // TTL + IsOn bool `field:"isOn"` // 启用状态 + Priority int32 `field:"priority"` // 优先级 + UpdatedAt uint64 `field:"updatedAt"` // 修改时间 + State uint8 `field:"state"` // 记录状态 +} + +type HTTPDNSCustomRuleOperator struct { + Id any // ID + AppId any // 应用DB ID + DomainId any // 域名ID + RuleName any // 规则名称 + LineScope any // 线路范围 + LineCarrier any // 运营商 + LineRegion any // 区域 + LineProvince any // 省份 + LineContinent any // 大洲 + LineCountry any // 国家 + TTL any // TTL + IsOn any // 启用状态 + Priority any // 优先级 + UpdatedAt any // 修改时间 + State any // 记录状态 +} + +func NewHTTPDNSCustomRuleOperator() *HTTPDNSCustomRuleOperator { + return &HTTPDNSCustomRuleOperator{} +} diff --git a/EdgeAPI/internal/db/models/httpdns_custom_rule_record_dao.go b/EdgeAPI/internal/db/models/httpdns_custom_rule_record_dao.go new file mode 100644 index 0000000..58aad00 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_custom_rule_record_dao.go @@ -0,0 +1,69 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/types" +) + +const ( + HTTPDNSCustomRuleRecordStateEnabled = 1 + HTTPDNSCustomRuleRecordStateDisabled = 0 +) + +type HTTPDNSCustomRuleRecordDAO dbs.DAO + +func NewHTTPDNSCustomRuleRecordDAO() *HTTPDNSCustomRuleRecordDAO { + return dbs.NewDAO(&HTTPDNSCustomRuleRecordDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSCustomRuleRecords", + Model: new(HTTPDNSCustomRuleRecord), + PkName: "id", + }, + }).(*HTTPDNSCustomRuleRecordDAO) +} + +var SharedHTTPDNSCustomRuleRecordDAO *HTTPDNSCustomRuleRecordDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSCustomRuleRecordDAO = NewHTTPDNSCustomRuleRecordDAO() + }) +} + +func (this *HTTPDNSCustomRuleRecordDAO) CreateRecord(tx *dbs.Tx, ruleId int64, recordType string, recordValue string, weight int32, sort int32) (int64, error) { + var op = NewHTTPDNSCustomRuleRecordOperator() + op.RuleId = ruleId + op.RecordType = recordType + op.RecordValue = recordValue + op.Weight = weight + op.Sort = sort + op.State = HTTPDNSCustomRuleRecordStateEnabled + err := this.Save(tx, op) + if err != nil { + return 0, err + } + return types.Int64(op.Id), nil +} + +func (this *HTTPDNSCustomRuleRecordDAO) DisableRecordsWithRuleId(tx *dbs.Tx, ruleId int64) error { + _, err := this.Query(tx). + Attr("ruleId", ruleId). + State(HTTPDNSCustomRuleRecordStateEnabled). + Set("state", HTTPDNSCustomRuleRecordStateDisabled). + Update() + return err +} + +func (this *HTTPDNSCustomRuleRecordDAO) ListEnabledRecordsWithRuleId(tx *dbs.Tx, ruleId int64) (result []*HTTPDNSCustomRuleRecord, err error) { + _, err = this.Query(tx). + State(HTTPDNSCustomRuleRecordStateEnabled). + Attr("ruleId", ruleId). + Asc("sort"). + AscPk(). + Slice(&result). + FindAll() + return +} diff --git a/EdgeAPI/internal/db/models/httpdns_custom_rule_record_model.go b/EdgeAPI/internal/db/models/httpdns_custom_rule_record_model.go new file mode 100644 index 0000000..c5128d0 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_custom_rule_record_model.go @@ -0,0 +1,26 @@ +package models + +// HTTPDNSCustomRuleRecord 自定义规则记录值 +type HTTPDNSCustomRuleRecord struct { + Id uint32 `field:"id"` // ID + RuleId uint32 `field:"ruleId"` // 规则ID + RecordType string `field:"recordType"` // 记录类型 + RecordValue string `field:"recordValue"` // 记录值 + Weight int32 `field:"weight"` // 权重 + Sort int32 `field:"sort"` // 顺序 + State uint8 `field:"state"` // 记录状态 +} + +type HTTPDNSCustomRuleRecordOperator struct { + Id any // ID + RuleId any // 规则ID + RecordType any // 记录类型 + RecordValue any // 记录值 + Weight any // 权重 + Sort any // 顺序 + State any // 记录状态 +} + +func NewHTTPDNSCustomRuleRecordOperator() *HTTPDNSCustomRuleRecordOperator { + return &HTTPDNSCustomRuleRecordOperator{} +} diff --git a/EdgeAPI/internal/db/models/httpdns_domain_dao.go b/EdgeAPI/internal/db/models/httpdns_domain_dao.go new file mode 100644 index 0000000..2330869 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_domain_dao.go @@ -0,0 +1,115 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/types" + "strings" + "time" +) + +const ( + HTTPDNSDomainStateEnabled = 1 + HTTPDNSDomainStateDisabled = 0 +) + +type HTTPDNSDomainDAO dbs.DAO + +func NewHTTPDNSDomainDAO() *HTTPDNSDomainDAO { + return dbs.NewDAO(&HTTPDNSDomainDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSDomains", + Model: new(HTTPDNSDomain), + PkName: "id", + }, + }).(*HTTPDNSDomainDAO) +} + +var SharedHTTPDNSDomainDAO *HTTPDNSDomainDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSDomainDAO = NewHTTPDNSDomainDAO() + }) +} + +func (this *HTTPDNSDomainDAO) CreateDomain(tx *dbs.Tx, appDbId int64, domain string, isOn bool) (int64, error) { + domain = strings.ToLower(strings.TrimSpace(domain)) + var op = NewHTTPDNSDomainOperator() + op.AppId = appDbId + op.Domain = domain + op.IsOn = isOn + op.CreatedAt = time.Now().Unix() + op.UpdatedAt = time.Now().Unix() + op.State = HTTPDNSDomainStateEnabled + err := this.Save(tx, op) + if err != nil { + return 0, err + } + return types.Int64(op.Id), nil +} + +func (this *HTTPDNSDomainDAO) DisableDomain(tx *dbs.Tx, domainId int64) error { + _, err := this.Query(tx). + Pk(domainId). + Set("state", HTTPDNSDomainStateDisabled). + Update() + return err +} + +func (this *HTTPDNSDomainDAO) DisableDomainsWithAppId(tx *dbs.Tx, appDbId int64) error { + _, err := this.Query(tx). + Attr("appId", appDbId). + State(HTTPDNSDomainStateEnabled). + Set("state", HTTPDNSDomainStateDisabled). + Set("updatedAt", time.Now().Unix()). + Update() + return err +} + +func (this *HTTPDNSDomainDAO) UpdateDomainStatus(tx *dbs.Tx, domainId int64, isOn bool) error { + _, err := this.Query(tx). + Pk(domainId). + State(HTTPDNSDomainStateEnabled). + Set("isOn", isOn). + Set("updatedAt", time.Now().Unix()). + Update() + return err +} + +func (this *HTTPDNSDomainDAO) FindEnabledDomain(tx *dbs.Tx, domainId int64) (*HTTPDNSDomain, error) { + one, err := this.Query(tx). + Pk(domainId). + State(HTTPDNSDomainStateEnabled). + Find() + if one == nil { + return nil, err + } + return one.(*HTTPDNSDomain), nil +} + +func (this *HTTPDNSDomainDAO) FindEnabledDomainWithAppAndName(tx *dbs.Tx, appDbId int64, domain string) (*HTTPDNSDomain, error) { + one, err := this.Query(tx). + State(HTTPDNSDomainStateEnabled). + Attr("appId", appDbId). + Attr("domain", strings.ToLower(strings.TrimSpace(domain))). + Find() + if one == nil { + return nil, err + } + return one.(*HTTPDNSDomain), nil +} + +func (this *HTTPDNSDomainDAO) ListEnabledDomainsWithAppId(tx *dbs.Tx, appDbId int64, keyword string) (result []*HTTPDNSDomain, err error) { + query := this.Query(tx). + State(HTTPDNSDomainStateEnabled). + Attr("appId", appDbId). + AscPk() + if len(keyword) > 0 { + query = query.Where("domain LIKE :kw").Param("kw", "%"+keyword+"%") + } + _, err = query.Slice(&result).FindAll() + return +} diff --git a/EdgeAPI/internal/db/models/httpdns_domain_model.go b/EdgeAPI/internal/db/models/httpdns_domain_model.go new file mode 100644 index 0000000..1b96478 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_domain_model.go @@ -0,0 +1,26 @@ +package models + +// HTTPDNSDomain 应用绑定域名 +type HTTPDNSDomain struct { + Id uint32 `field:"id"` // ID + AppId uint32 `field:"appId"` // 应用DB ID + Domain string `field:"domain"` // 业务域名 + IsOn bool `field:"isOn"` // 是否启用 + CreatedAt uint64 `field:"createdAt"` // 创建时间 + UpdatedAt uint64 `field:"updatedAt"` // 修改时间 + State uint8 `field:"state"` // 记录状态 +} + +type HTTPDNSDomainOperator struct { + Id any // ID + AppId any // 应用DB ID + Domain any // 业务域名 + IsOn any // 是否启用 + CreatedAt any // 创建时间 + UpdatedAt any // 修改时间 + State any // 记录状态 +} + +func NewHTTPDNSDomainOperator() *HTTPDNSDomainOperator { + return &HTTPDNSDomainOperator{} +} diff --git a/EdgeAPI/internal/db/models/httpdns_node_dao.go b/EdgeAPI/internal/db/models/httpdns_node_dao.go new file mode 100644 index 0000000..a5bf0d3 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_node_dao.go @@ -0,0 +1,273 @@ +package models + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/rands" + "github.com/iwind/TeaGo/types" + "time" +) + +const ( + HTTPDNSNodeStateEnabled = 1 // 已启用 + HTTPDNSNodeStateDisabled = 0 // 已禁用 +) + +type HTTPDNSNodeDAO dbs.DAO + +func NewHTTPDNSNodeDAO() *HTTPDNSNodeDAO { + return dbs.NewDAO(&HTTPDNSNodeDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSNodes", + Model: new(HTTPDNSNode), + PkName: "id", + }, + }).(*HTTPDNSNodeDAO) +} + +var SharedHTTPDNSNodeDAO *HTTPDNSNodeDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSNodeDAO = NewHTTPDNSNodeDAO() + }) +} + +// FindEnabledNodeIdWithUniqueId 根据唯一ID获取启用中的HTTPDNS节点ID +func (this *HTTPDNSNodeDAO) FindEnabledNodeIdWithUniqueId(tx *dbs.Tx, uniqueId string) (int64, error) { + return this.Query(tx). + Attr("uniqueId", uniqueId). + Attr("state", HTTPDNSNodeStateEnabled). + ResultPk(). + FindInt64Col(0) +} + +// CreateNode 创建节点 +func (this *HTTPDNSNodeDAO) CreateNode(tx *dbs.Tx, clusterId int64, name string, installDir string, isOn bool) (int64, error) { + uniqueId := rands.HexString(32) + secret := rands.String(32) + err := SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleHTTPDNS) + if err != nil { + return 0, err + } + + var op = NewHTTPDNSNodeOperator() + op.ClusterId = clusterId + op.Name = name + op.IsOn = isOn + op.IsUp = false + op.IsInstalled = false + op.IsActive = false + op.UniqueId = uniqueId + op.Secret = secret + op.InstallDir = installDir + op.CreatedAt = time.Now().Unix() + op.UpdatedAt = time.Now().Unix() + op.State = HTTPDNSNodeStateEnabled + err = this.Save(tx, op) + if err != nil { + return 0, err + } + return types.Int64(op.Id), nil +} + +// UpdateNode 更新节点 +func (this *HTTPDNSNodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, installDir string, isOn bool) error { + var op = NewHTTPDNSNodeOperator() + op.Id = nodeId + op.Name = name + op.InstallDir = installDir + op.IsOn = isOn + op.UpdatedAt = time.Now().Unix() + return this.Save(tx, op) +} + +// DisableNode 禁用节点 +func (this *HTTPDNSNodeDAO) DisableNode(tx *dbs.Tx, nodeId int64) error { + node, err := this.FindEnabledNode(tx, nodeId) + if err != nil { + return err + } + if node == nil { + return nil + } + + _, err = this.Query(tx). + Pk(nodeId). + Set("state", HTTPDNSNodeStateDisabled). + Update() + if err != nil { + return err + } + + _, err = SharedApiTokenDAO.Query(tx). + Attr("nodeId", node.UniqueId). + Attr("role", nodeconfigs.NodeRoleHTTPDNS). + Set("state", ApiTokenStateDisabled). + Update() + return err +} + +// FindEnabledNode 查找启用节点 +func (this *HTTPDNSNodeDAO) FindEnabledNode(tx *dbs.Tx, nodeId int64) (*HTTPDNSNode, error) { + one, err := this.Query(tx). + Pk(nodeId). + Attr("state", HTTPDNSNodeStateEnabled). + Find() + if one == nil { + return nil, err + } + return one.(*HTTPDNSNode), nil +} + +// FindNodeClusterId 查询节点所属集群ID +func (this *HTTPDNSNodeDAO) FindNodeClusterId(tx *dbs.Tx, nodeId int64) (int64, error) { + return this.Query(tx). + Pk(nodeId). + Attr("state", HTTPDNSNodeStateEnabled). + Result("clusterId"). + FindInt64Col(0) +} + +// ListEnabledNodes 列出节点 +func (this *HTTPDNSNodeDAO) ListEnabledNodes(tx *dbs.Tx, clusterId int64) (result []*HTTPDNSNode, err error) { + query := this.Query(tx). + State(HTTPDNSNodeStateEnabled). + AscPk() + if clusterId > 0 { + query = query.Attr("clusterId", clusterId) + } + _, err = query.Slice(&result).FindAll() + return +} + +// UpdateNodeStatus 更新节点状态 +func (this *HTTPDNSNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, isUp bool, isInstalled bool, isActive bool, statusJSON []byte, installStatusJSON []byte) error { + var op = NewHTTPDNSNodeOperator() + op.Id = nodeId + op.IsUp = isUp + op.IsInstalled = isInstalled + op.IsActive = isActive + op.UpdatedAt = time.Now().Unix() + if len(statusJSON) > 0 { + op.Status = statusJSON + } + if len(installStatusJSON) > 0 { + mergedStatusJSON, mergeErr := this.mergeInstallStatusJSON(tx, nodeId, installStatusJSON) + if mergeErr != nil { + return mergeErr + } + op.InstallStatus = mergedStatusJSON + } + return this.Save(tx, op) +} + +// UpdateNodeInstallStatus 更新节点安装状态 +func (this *HTTPDNSNodeDAO) UpdateNodeInstallStatus(tx *dbs.Tx, nodeId int64, installStatus *NodeInstallStatus) error { + if installStatus == nil { + return nil + } + + // Read existing installStatus to preserve custom fields like 'ssh' and 'ipAddr' + raw, err := this.Query(tx).Pk(nodeId).Result("installStatus").FindBytesCol() + if err != nil { + return err + } + + var m = map[string]interface{}{} + if len(raw) > 0 { + _ = json.Unmarshal(raw, &m) + } + + // Overlay standard install status fields + statusData, err := json.Marshal(installStatus) + if err != nil { + return err + } + var newStatusMap = map[string]interface{}{} + _ = json.Unmarshal(statusData, &newStatusMap) + + for k, v := range newStatusMap { + m[k] = v + } + + // Re-marshal the merged map + mergedData, err := json.Marshal(m) + if err != nil { + return err + } + + _, err = this.Query(tx). + Pk(nodeId). + Set("installStatus", mergedData). + Set("updatedAt", time.Now().Unix()). + Update() + return err +} + +func (this *HTTPDNSNodeDAO) mergeInstallStatusJSON(tx *dbs.Tx, nodeId int64, patch []byte) ([]byte, error) { + if len(patch) == 0 { + return patch, nil + } + + raw, err := this.Query(tx).Pk(nodeId).Result("installStatus").FindBytesCol() + if err != nil { + return nil, err + } + + merged := map[string]interface{}{} + if len(raw) > 0 { + _ = json.Unmarshal(raw, &merged) + } + patchMap := map[string]interface{}{} + if len(patch) > 0 { + _ = json.Unmarshal(patch, &patchMap) + } + + for k, v := range patchMap { + merged[k] = v + } + + data, err := json.Marshal(merged) + if err != nil { + return nil, err + } + return data, nil +} + +// FindNodeInstallStatus 读取节点安装状态 +func (this *HTTPDNSNodeDAO) FindNodeInstallStatus(tx *dbs.Tx, nodeId int64) (*NodeInstallStatus, error) { + raw, err := this.Query(tx). + Pk(nodeId). + State(HTTPDNSNodeStateEnabled). + Result("installStatus"). + FindBytesCol() + if err != nil { + return nil, err + } + if len(raw) == 0 { + return nil, nil + } + + installStatus := &NodeInstallStatus{} + err = json.Unmarshal(raw, installStatus) + if err != nil { + return nil, err + } + return installStatus, nil +} + +// UpdateNodeIsInstalled 更新节点安装状态位 +func (this *HTTPDNSNodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled bool) error { + _, err := this.Query(tx). + Pk(nodeId). + State(HTTPDNSNodeStateEnabled). + Set("isInstalled", isInstalled). + Set("updatedAt", time.Now().Unix()). + Update() + return err +} diff --git a/EdgeAPI/internal/db/models/httpdns_node_model.go b/EdgeAPI/internal/db/models/httpdns_node_model.go new file mode 100644 index 0000000..80a15de --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_node_model.go @@ -0,0 +1,44 @@ +package models + +import "github.com/iwind/TeaGo/dbs" + +// HTTPDNSNode HTTPDNS节点 +type HTTPDNSNode struct { + Id uint32 `field:"id"` // ID + ClusterId uint32 `field:"clusterId"` // 集群ID + Name string `field:"name"` // 节点名称 + IsOn bool `field:"isOn"` // 是否启用 + IsUp bool `field:"isUp"` // 是否在线 + IsInstalled bool `field:"isInstalled"` // 是否已安装 + IsActive bool `field:"isActive"` // 是否活跃 + UniqueId string `field:"uniqueId"` // 节点唯一ID + Secret string `field:"secret"` // 节点密钥 + InstallDir string `field:"installDir"` // 安装目录 + Status dbs.JSON `field:"status"` // 运行状态快照 + InstallStatus dbs.JSON `field:"installStatus"` // 安装状态 + CreatedAt uint64 `field:"createdAt"` // 创建时间 + UpdatedAt uint64 `field:"updatedAt"` // 修改时间 + State uint8 `field:"state"` // 记录状态 +} + +type HTTPDNSNodeOperator struct { + Id any // ID + ClusterId any // 集群ID + Name any // 节点名称 + IsOn any // 是否启用 + IsUp any // 是否在线 + IsInstalled any // 是否已安装 + IsActive any // 是否活跃 + UniqueId any // 节点唯一ID + Secret any // 节点密钥 + InstallDir any // 安装目录 + Status any // 运行状态快照 + InstallStatus any // 安装状态 + CreatedAt any // 创建时间 + UpdatedAt any // 修改时间 + State any // 记录状态 +} + +func NewHTTPDNSNodeOperator() *HTTPDNSNodeOperator { + return &HTTPDNSNodeOperator{} +} diff --git a/EdgeAPI/internal/db/models/httpdns_runtime_log_dao.go b/EdgeAPI/internal/db/models/httpdns_runtime_log_dao.go new file mode 100644 index 0000000..4d53581 --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_runtime_log_dao.go @@ -0,0 +1,108 @@ +package models + +import ( + "strconv" + "time" + + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" +) + +type HTTPDNSRuntimeLogDAO dbs.DAO + +func NewHTTPDNSRuntimeLogDAO() *HTTPDNSRuntimeLogDAO { + return dbs.NewDAO(&HTTPDNSRuntimeLogDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPDNSRuntimeLogs", + Model: new(HTTPDNSRuntimeLog), + PkName: "id", + }, + }).(*HTTPDNSRuntimeLogDAO) +} + +var SharedHTTPDNSRuntimeLogDAO *HTTPDNSRuntimeLogDAO + +func init() { + dbs.OnReady(func() { + SharedHTTPDNSRuntimeLogDAO = NewHTTPDNSRuntimeLogDAO() + }) +} + +func (this *HTTPDNSRuntimeLogDAO) CreateLog(tx *dbs.Tx, log *HTTPDNSRuntimeLog) error { + lastLog, err := this.Query(tx). + Result("id", "clusterId", "nodeId", "level", "type", "module", "description", "createdAt"). + DescPk(). + Find() + if err != nil { + return err + } + if lastLog != nil { + nodeLog := lastLog.(*HTTPDNSRuntimeLog) + if nodeLog.ClusterId == log.ClusterId && + nodeLog.NodeId == log.NodeId && + nodeLog.Level == log.Level && + nodeLog.Type == log.Type && + nodeLog.Module == log.Module && + nodeLog.Description == log.Description && + time.Now().Unix()-int64(nodeLog.CreatedAt) < 1800 { + + count := log.Count + if count <= 0 { + count = 1 + } + + return this.Query(tx). + Pk(nodeLog.Id). + Set("count", dbs.SQL("count+"+strconv.FormatInt(count, 10))). + UpdateQuickly() + } + } + + var op = NewHTTPDNSRuntimeLogOperator() + op.ClusterId = log.ClusterId + op.NodeId = log.NodeId + op.Level = log.Level + op.Type = log.Type + op.Module = log.Module + op.Description = log.Description + op.Count = log.Count + op.RequestId = log.RequestId + op.CreatedAt = log.CreatedAt + op.Day = log.Day + return this.Save(tx, op) +} + +func (this *HTTPDNSRuntimeLogDAO) BuildListQuery(tx *dbs.Tx, day string, clusterId int64, nodeId int64, level string, keyword string) *dbs.Query { + query := this.Query(tx).DescPk() + if len(day) > 0 { + query = query.Attr("day", day) + } + if clusterId > 0 { + query = query.Attr("clusterId", clusterId) + } + if nodeId > 0 { + query = query.Attr("nodeId", nodeId) + } + if len(level) > 0 { + query = query.Attr("level", level) + } + if len(keyword) > 0 { + query = query.Where("(type LIKE :kw OR module LIKE :kw OR description LIKE :kw OR requestId LIKE :kw)").Param("kw", "%"+keyword+"%") + } + return query +} + +func (this *HTTPDNSRuntimeLogDAO) CountLogs(tx *dbs.Tx, day string, clusterId int64, nodeId int64, level string, keyword string) (int64, error) { + return this.BuildListQuery(tx, day, clusterId, nodeId, level, keyword).Count() +} + +func (this *HTTPDNSRuntimeLogDAO) ListLogs(tx *dbs.Tx, day string, clusterId int64, nodeId int64, level string, keyword string, offset int64, size int64) (result []*HTTPDNSRuntimeLog, err error) { + _, err = this.BuildListQuery(tx, day, clusterId, nodeId, level, keyword). + Offset(offset). + Limit(size). + Slice(&result). + FindAll() + return +} diff --git a/EdgeAPI/internal/db/models/httpdns_runtime_log_model.go b/EdgeAPI/internal/db/models/httpdns_runtime_log_model.go new file mode 100644 index 0000000..fe26dda --- /dev/null +++ b/EdgeAPI/internal/db/models/httpdns_runtime_log_model.go @@ -0,0 +1,34 @@ +package models + +// HTTPDNSRuntimeLog 运行日志 +type HTTPDNSRuntimeLog struct { + Id uint64 `field:"id"` // ID + ClusterId uint32 `field:"clusterId"` // 集群ID + NodeId uint32 `field:"nodeId"` // 节点ID + Level string `field:"level"` // 级别 + Type string `field:"type"` // 类型 + Module string `field:"module"` // 模块 + Description string `field:"description"` // 详情 + Count int64 `field:"count"` // 次数 + RequestId string `field:"requestId"` // 请求ID + CreatedAt uint64 `field:"createdAt"` // 创建时间 + Day string `field:"day"` // YYYYMMDD +} + +type HTTPDNSRuntimeLogOperator struct { + Id any // ID + ClusterId any // 集群ID + NodeId any // 节点ID + Level any // 级别 + Type any // 类型 + Module any // 模块 + Description any // 详情 + Count any // 次数 + RequestId any // 请求ID + CreatedAt any // 创建时间 + Day any // YYYYMMDD +} + +func NewHTTPDNSRuntimeLogOperator() *HTTPDNSRuntimeLogOperator { + return &HTTPDNSRuntimeLogOperator{} +} diff --git a/EdgeAPI/internal/db/models/node_task_dao.go b/EdgeAPI/internal/db/models/node_task_dao.go index df317dd..1a3d90a 100644 --- a/EdgeAPI/internal/db/models/node_task_dao.go +++ b/EdgeAPI/internal/db/models/node_task_dao.go @@ -15,35 +15,41 @@ import ( type NodeTaskType = string const ( - // CDN相关 + // CDN鐩稿叧 - NodeTaskTypeConfigChanged NodeTaskType = "configChanged" // 节点整体配置变化 - NodeTaskTypeDDosProtectionChanged NodeTaskType = "ddosProtectionChanged" // 节点DDoS配置变更 - NodeTaskTypeGlobalServerConfigChanged NodeTaskType = "globalServerConfigChanged" // 全局服务设置变化 - NodeTaskTypeIPListDeleted NodeTaskType = "ipListDeleted" // IPList被删除 - NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged" // IP条目变更 - NodeTaskTypeNodeVersionChanged NodeTaskType = "nodeVersionChanged" // 节点版本变化 - NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged" // 脚本配置变化 - NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged" // 节点级别变化 - NodeTaskTypeUserServersStateChanged NodeTaskType = "userServersStateChanged" // 用户服务状态变化 - NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM策略变化 - NodeTaskTypeHTTPPagesPolicyChanged NodeTaskType = "httpPagesPolicyChanged" // 自定义页面变化 - NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC策略变化 - NodeTaskTypeHTTP3PolicyChanged NodeTaskType = "http3PolicyChanged" // HTTP3策略变化 - NodeTaskTypeNetworkSecurityPolicyChanged NodeTaskType = "networkSecurityPolicyChanged" // 网络安全策略变化 - NodeTaskTypeWebPPolicyChanged NodeTaskType = "webPPolicyChanged" // WebP策略变化 - NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务 - NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA配置变化 - NodeTaskTypePlanChanged NodeTaskType = "planChanged" // 套餐变化 + NodeTaskTypeConfigChanged NodeTaskType = "configChanged" // 鑺傜偣鏁翠綋閰嶇疆鍙樺寲 + NodeTaskTypeDDosProtectionChanged NodeTaskType = "ddosProtectionChanged" // 鑺傜偣DDoS閰嶇疆鍙樻洿 + NodeTaskTypeGlobalServerConfigChanged NodeTaskType = "globalServerConfigChanged" // 鍏ㄥ眬鏈嶅姟璁剧疆鍙樺寲 + NodeTaskTypeIPListDeleted NodeTaskType = "ipListDeleted" // IPList琚垹闄? + NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged" // IP鏉$洰鍙樻洿 + NodeTaskTypeNodeVersionChanged NodeTaskType = "nodeVersionChanged" // 鑺傜偣鐗堟湰鍙樺寲 + NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged" // 鑴氭湰閰嶇疆鍙樺寲 + NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged" // 鑺傜偣绾у埆鍙樺寲 + NodeTaskTypeUserServersStateChanged NodeTaskType = "userServersStateChanged" // 鐢ㄦ埛鏈嶅姟鐘舵€佸彉鍖? + NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM绛栫暐鍙樺寲 + NodeTaskTypeHTTPPagesPolicyChanged NodeTaskType = "httpPagesPolicyChanged" // 鑷畾涔夐〉闈㈠彉鍖? + NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC绛栫暐鍙樺寲 + NodeTaskTypeHTTP3PolicyChanged NodeTaskType = "http3PolicyChanged" // HTTP3绛栫暐鍙樺寲 + NodeTaskTypeNetworkSecurityPolicyChanged NodeTaskType = "networkSecurityPolicyChanged" // 缃戠粶瀹夊叏绛栫暐鍙樺寲 + NodeTaskTypeWebPPolicyChanged NodeTaskType = "webPPolicyChanged" // WebP绛栫暐鍙樺寲 + NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 鏇存柊涓€缁勬湇鍔? + NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA閰嶇疆鍙樺寲 + NodeTaskTypePlanChanged NodeTaskType = "planChanged" // 濂楅鍙樺寲 - // NS相关 + // NS鐩稿叧 NSNodeTaskTypeConfigChanged NodeTaskType = "nsConfigChanged" NSNodeTaskTypeDomainChanged NodeTaskType = "nsDomainChanged" NSNodeTaskTypeRecordChanged NodeTaskType = "nsRecordChanged" NSNodeTaskTypeRouteChanged NodeTaskType = "nsRouteChanged" NSNodeTaskTypeKeyChanged NodeTaskType = "nsKeyChanged" - NSNodeTaskTypeDDosProtectionChanged NodeTaskType = "nsDDoSProtectionChanged" // 节点DDoS配置变更 + NSNodeTaskTypeDDosProtectionChanged NodeTaskType = "nsDDoSProtectionChanged" // 鑺傜偣DDoS閰嶇疆鍙樻洿 + // HTTPDNS相关 + HTTPDNSNodeTaskTypeConfigChanged NodeTaskType = "httpdnsConfigChanged" + HTTPDNSNodeTaskTypeAppChanged NodeTaskType = "httpdnsAppChanged" + HTTPDNSNodeTaskTypeDomainChanged NodeTaskType = "httpdnsDomainChanged" + HTTPDNSNodeTaskTypeRuleChanged NodeTaskType = "httpdnsRuleChanged" + HTTPDNSNodeTaskTypeTLSChanged NodeTaskType = "httpdnsTLSChanged" ) type NodeTaskDAO dbs.DAO @@ -67,15 +73,15 @@ func init() { }) } -// CreateNodeTask 创建单个节点任务 +// CreateNodeTask 鍒涘缓鍗曚釜鑺傜偣浠诲姟 func (this *NodeTaskDAO) CreateNodeTask(tx *dbs.Tx, role string, clusterId int64, nodeId int64, userId int64, serverId int64, taskType NodeTaskType) error { if clusterId <= 0 || nodeId <= 0 { return nil } var uniqueId = role + "@" + types.String(nodeId) + "@node@" + types.String(serverId) + "@" + taskType - // 用户信息 - // 没有直接加入到 uniqueId 中,是为了兼容以前的字段值 + // 鐢ㄦ埛淇℃伅 + // 娌℃湁鐩存帴鍔犲叆鍒?uniqueId 涓紝鏄负浜嗗吋瀹逛互鍓嶇殑瀛楁鍊? if userId > 0 { uniqueId += "@" + types.String(userId) } @@ -113,7 +119,7 @@ func (this *NodeTaskDAO) CreateNodeTask(tx *dbs.Tx, role string, clusterId int64 return err } -// CreateClusterTask 创建集群任务 +// CreateClusterTask 鍒涘缓闆嗙兢浠诲姟 func (this *NodeTaskDAO) CreateClusterTask(tx *dbs.Tx, role string, clusterId int64, userId int64, serverId int64, taskType NodeTaskType) error { if clusterId <= 0 { return nil @@ -121,8 +127,8 @@ func (this *NodeTaskDAO) CreateClusterTask(tx *dbs.Tx, role string, clusterId in var uniqueId = role + "@" + types.String(clusterId) + "@" + types.String(serverId) + "@cluster@" + taskType - // 用户信息 - // 没有直接加入到 uniqueId 中,是为了兼容以前的字段值 + // 鐢ㄦ埛淇℃伅 + // 娌℃湁鐩存帴鍔犲叆鍒?uniqueId 涓紝鏄负浜嗗吋瀹逛互鍓嶇殑瀛楁鍊? if userId > 0 { uniqueId += "@" + types.String(userId) } @@ -155,7 +161,7 @@ func (this *NodeTaskDAO) CreateClusterTask(tx *dbs.Tx, role string, clusterId in return err } -// ExtractNodeClusterTask 分解边缘节点集群任务 +// ExtractNodeClusterTask 鍒嗚В杈圭紭鑺傜偣闆嗙兢浠诲姟 func (this *NodeTaskDAO) ExtractNodeClusterTask(tx *dbs.Tx, clusterId int64, userId int64, serverId int64, taskType NodeTaskType) error { nodeIds, err := SharedNodeDAO.FindAllNodeIdsMatch(tx, clusterId, true, configutils.BoolStateYes) if err != nil { @@ -193,7 +199,7 @@ func (this *NodeTaskDAO) ExtractNodeClusterTask(tx *dbs.Tx, clusterId int64, use return nil } -// ExtractAllClusterTasks 分解所有集群任务 +// ExtractAllClusterTasks 鍒嗚В鎵€鏈夐泦缇や换鍔? func (this *NodeTaskDAO) ExtractAllClusterTasks(tx *dbs.Tx, role string) error { ones, err := this.Query(tx). Attr("role", role). @@ -216,12 +222,17 @@ func (this *NodeTaskDAO) ExtractAllClusterTasks(tx *dbs.Tx, role string) error { if err != nil { return err } + case nodeconfigs.NodeRoleHTTPDNS: + err = this.ExtractHTTPDNSClusterTask(tx, clusterId, one.(*NodeTask).Type) + if err != nil { + return err + } } } return nil } -// DeleteAllClusterTasks 删除集群所有相关任务 +// DeleteAllClusterTasks 鍒犻櫎闆嗙兢鎵€鏈夌浉鍏充换鍔? func (this *NodeTaskDAO) DeleteAllClusterTasks(tx *dbs.Tx, role string, clusterId int64) error { _, err := this.Query(tx). Attr("role", role). @@ -230,7 +241,7 @@ func (this *NodeTaskDAO) DeleteAllClusterTasks(tx *dbs.Tx, role string, clusterI return err } -// DeleteNodeTasks 删除节点相关任务 +// DeleteNodeTasks 鍒犻櫎鑺傜偣鐩稿叧浠诲姟 func (this *NodeTaskDAO) DeleteNodeTasks(tx *dbs.Tx, role string, nodeId int64) error { _, err := this.Query(tx). Attr("role", role). @@ -239,13 +250,13 @@ func (this *NodeTaskDAO) DeleteNodeTasks(tx *dbs.Tx, role string, nodeId int64) return err } -// DeleteAllNodeTasks 删除所有节点相关任务 +// DeleteAllNodeTasks 鍒犻櫎鎵€鏈夎妭鐐圭浉鍏充换鍔? func (this *NodeTaskDAO) DeleteAllNodeTasks(tx *dbs.Tx) error { return this.Query(tx). DeleteQuickly() } -// FindDoingNodeTasks 查询一个节点的所有任务 +// FindDoingNodeTasks 鏌ヨ涓€涓妭鐐圭殑鎵€鏈変换鍔? func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int64, version int64) (result []*NodeTask, err error) { if nodeId <= 0 { return @@ -256,10 +267,10 @@ func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int6 UseIndex("nodeId"). Asc("version") if version > 0 { - query.Lt("LENGTH(version)", 19) // 兼容以往版本 + query.Lt("LENGTH(version)", 19) // 鍏煎浠ュ線鐗堟湰 query.Gt("version", version) } else { - // 第一次访问时只取当前正在执行的或者执行失败的 + // 绗竴娆¤闂椂鍙彇褰撳墠姝e湪鎵ц鐨勬垨鑰呮墽琛屽け璐ョ殑 query.Where("(isDone=0 OR (isDone=1 AND isOk=0))") } _, err = query. @@ -268,10 +279,10 @@ func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int6 return } -// UpdateNodeTaskDone 修改节点任务的完成状态 +// UpdateNodeTaskDone 淇敼鑺傜偣浠诲姟鐨勫畬鎴愮姸鎬? func (this *NodeTaskDAO) UpdateNodeTaskDone(tx *dbs.Tx, taskId int64, isOk bool, errorMessage string) error { if isOk { - // 特殊任务删除 + // 鐗规畩浠诲姟鍒犻櫎 taskType, err := this.Query(tx). Pk(taskId). Result("type"). @@ -286,7 +297,7 @@ func (this *NodeTaskDAO) UpdateNodeTaskDone(tx *dbs.Tx, taskId int64, isOk bool, } } - // 其他任务标记为完成 + // 鍏朵粬浠诲姟鏍囪涓哄畬鎴? var query = this.Query(tx). Pk(taskId) if !isOk { @@ -305,7 +316,7 @@ func (this *NodeTaskDAO) UpdateNodeTaskDone(tx *dbs.Tx, taskId int64, isOk bool, return err } -// FindAllDoingTaskClusterIds 查找正在更新的集群IDs +// FindAllDoingTaskClusterIds 鏌ユ壘姝e湪鏇存柊鐨勯泦缇Ds func (this *NodeTaskDAO) FindAllDoingTaskClusterIds(tx *dbs.Tx, role string) ([]int64, error) { ones, _, err := this.Query(tx). Result("DISTINCT(clusterId) AS clusterId"). @@ -322,7 +333,7 @@ func (this *NodeTaskDAO) FindAllDoingTaskClusterIds(tx *dbs.Tx, role string) ([] return result, nil } -// FindAllDoingNodeTasksWithClusterId 查询某个集群下所有的任务 +// FindAllDoingNodeTasksWithClusterId 鏌ヨ鏌愪釜闆嗙兢涓嬫墍鏈夌殑浠诲姟 func (this *NodeTaskDAO) FindAllDoingNodeTasksWithClusterId(tx *dbs.Tx, role string, clusterId int64) (result []*NodeTask, err error) { _, err = this.Query(tx). Attr("role", role). @@ -337,7 +348,7 @@ func (this *NodeTaskDAO) FindAllDoingNodeTasksWithClusterId(tx *dbs.Tx, role str return } -// FindAllDoingNodeIds 查询有任务的节点IDs +// FindAllDoingNodeIds 鏌ヨ鏈変换鍔$殑鑺傜偣IDs func (this *NodeTaskDAO) FindAllDoingNodeIds(tx *dbs.Tx, role string) ([]int64, error) { ones, err := this.Query(tx). Result("DISTINCT(nodeId) AS nodeId"). @@ -356,7 +367,7 @@ func (this *NodeTaskDAO) FindAllDoingNodeIds(tx *dbs.Tx, role string) ([]int64, return result, nil } -// ExistsDoingNodeTasks 检查是否有正在执行的任务 +// ExistsDoingNodeTasks 妫€鏌ユ槸鍚︽湁姝e湪鎵ц鐨勪换鍔? func (this *NodeTaskDAO) ExistsDoingNodeTasks(tx *dbs.Tx, role string, excludeTypes []NodeTaskType) (bool, error) { var query = this.Query(tx). Attr("role", role). @@ -370,7 +381,7 @@ func (this *NodeTaskDAO) ExistsDoingNodeTasks(tx *dbs.Tx, role string, excludeTy return query.Exist() } -// ExistsErrorNodeTasks 是否有错误的任务 +// ExistsErrorNodeTasks 鏄惁鏈夐敊璇殑浠诲姟 func (this *NodeTaskDAO) ExistsErrorNodeTasks(tx *dbs.Tx, role string, excludeTypes []NodeTaskType) (bool, error) { var query = this.Query(tx). Attr("role", role). @@ -383,7 +394,7 @@ func (this *NodeTaskDAO) ExistsErrorNodeTasks(tx *dbs.Tx, role string, excludeTy return query.Exist() } -// DeleteNodeTask 删除任务 +// DeleteNodeTask 鍒犻櫎浠诲姟 func (this *NodeTaskDAO) DeleteNodeTask(tx *dbs.Tx, taskId int64) error { _, err := this.Query(tx). Pk(taskId). @@ -391,7 +402,7 @@ func (this *NodeTaskDAO) DeleteNodeTask(tx *dbs.Tx, taskId int64) error { return err } -// CountDoingNodeTasks 计算正在执行的任务 +// CountDoingNodeTasks 璁$畻姝e湪鎵ц鐨勪换鍔? func (this *NodeTaskDAO) CountDoingNodeTasks(tx *dbs.Tx, role string) (int64, error) { return this.Query(tx). Attr("isDone", 0). @@ -400,7 +411,7 @@ func (this *NodeTaskDAO) CountDoingNodeTasks(tx *dbs.Tx, role string) (int64, er Count() } -// FindNotifyingNodeTasks 查找需要通知的任务 +// FindNotifyingNodeTasks 鏌ユ壘闇€瑕侀€氱煡鐨勪换鍔? func (this *NodeTaskDAO) FindNotifyingNodeTasks(tx *dbs.Tx, role string, size int64) (result []*NodeTask, err error) { _, err = this.Query(tx). Attr("role", role). @@ -413,7 +424,7 @@ func (this *NodeTaskDAO) FindNotifyingNodeTasks(tx *dbs.Tx, role string, size in return } -// UpdateTasksNotified 设置任务已通知 +// UpdateTasksNotified 璁剧疆浠诲姟宸查€氱煡 func (this *NodeTaskDAO) UpdateTasksNotified(tx *dbs.Tx, taskIds []int64) error { if len(taskIds) == 0 { return nil @@ -430,7 +441,7 @@ func (this *NodeTaskDAO) UpdateTasksNotified(tx *dbs.Tx, taskIds []int64) error return nil } -// 生成一个版本号 +// 鐢熸垚涓€涓増鏈彿 func (this *NodeTaskDAO) increaseVersion(tx *dbs.Tx) (version int64, err error) { return SharedSysLockerDAO.Increase(tx, "NODE_TASK_VERSION", 0) } diff --git a/EdgeAPI/internal/db/models/node_task_dao_httpdns.go b/EdgeAPI/internal/db/models/node_task_dao_httpdns.go new file mode 100644 index 0000000..b07a685 --- /dev/null +++ b/EdgeAPI/internal/db/models/node_task_dao_httpdns.go @@ -0,0 +1,47 @@ +package models + +import ( + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" + "github.com/iwind/TeaGo/dbs" +) + +// ExtractHTTPDNSClusterTask 分解HTTPDNS节点集群任务 +func (this *NodeTaskDAO) ExtractHTTPDNSClusterTask(tx *dbs.Tx, clusterId int64, taskType NodeTaskType) error { + nodes, err := SharedHTTPDNSNodeDAO.ListEnabledNodes(tx, clusterId) + if err != nil { + return err + } + + _, err = this.Query(tx). + Attr("role", nodeconfigs.NodeRoleHTTPDNS). + Attr("clusterId", clusterId). + Gt("nodeId", 0). + Attr("type", taskType). + Delete() + if err != nil { + return err + } + + for _, node := range nodes { + if !node.IsOn { + continue + } + + err = this.CreateNodeTask(tx, nodeconfigs.NodeRoleHTTPDNS, clusterId, int64(node.Id), 0, 0, taskType) + if err != nil { + return err + } + } + + _, err = this.Query(tx). + Attr("role", nodeconfigs.NodeRoleHTTPDNS). + Attr("clusterId", clusterId). + Attr("nodeId", 0). + Attr("type", taskType). + Delete() + if err != nil { + return err + } + + return nil +} diff --git a/EdgeAPI/internal/installers/fluent_bit.go b/EdgeAPI/internal/installers/fluent_bit.go index 2272230..09ab0ff 100644 --- a/EdgeAPI/internal/installers/fluent_bit.go +++ b/EdgeAPI/internal/installers/fluent_bit.go @@ -343,6 +343,8 @@ func mapNodeRole(role nodeconfigs.NodeRole) (string, error) { return fluentBitRoleNode, nil case nodeconfigs.NodeRoleDNS: return fluentBitRoleDNS, nil + case nodeconfigs.NodeRoleHTTPDNS: + return fluentBitRoleDNS, nil default: return "", fmt.Errorf("unsupported fluent-bit role '%s'", role) } diff --git a/EdgeAPI/internal/installers/installer_httpdns_node.go b/EdgeAPI/internal/installers/installer_httpdns_node.go new file mode 100644 index 0000000..67ff300 --- /dev/null +++ b/EdgeAPI/internal/installers/installer_httpdns_node.go @@ -0,0 +1,230 @@ +package installers + +import ( + "bytes" + "errors" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" +) + +type HTTPDNSNodeInstaller struct { + BaseInstaller +} + +func (i *HTTPDNSNodeInstaller) Install(dir string, params interface{}, installStatus *models.NodeInstallStatus) error { + if params == nil { + return errors.New("'params' required for node installation") + } + nodeParams, ok := params.(*NodeParams) + if !ok { + return errors.New("'params' should be *NodeParams") + } + err := nodeParams.Validate() + if err != nil { + return fmt.Errorf("params validation: %w", err) + } + + installRootDir, appDir := resolveHTTPDNSInstallPaths(dir) + + _, err = i.client.Stat(installRootDir) + if err != nil { + err = i.client.MkdirAll(installRootDir) + if err != nil { + installStatus.ErrorCode = "CREATE_ROOT_DIRECTORY_FAILED" + return fmt.Errorf("create directory '%s' failed: %w", installRootDir, err) + } + } + + env, err := i.InstallHelper(installRootDir, nodeconfigs.NodeRoleHTTPDNS) + if err != nil { + installStatus.ErrorCode = "INSTALL_HELPER_FAILED" + return err + } + + filePrefix := "edge-httpdns-" + env.OS + "-" + env.Arch + zipFile, err := i.LookupLatestInstallerForTarget(filePrefix, env) + if err != nil { + return err + } + if len(zipFile) == 0 { + return errors.New("can not find installer file for " + env.OS + "/" + env.Arch + ", expected '" + filePrefix + "-v*.zip' or distro-specific '" + filePrefix + "-{ubuntu22.04|amzn2023}-v*.zip'") + } + + targetZip, err := i.copyZipToRemote(installRootDir, zipFile) + if err != nil { + return err + } + + if !nodeParams.IsUpgrading { + _, stderr, testErr := i.client.Exec(env.HelperPath + " -cmd=test") + if testErr != nil { + return fmt.Errorf("test failed: %w", testErr) + } + if len(stderr) > 0 { + return errors.New("test failed: " + stderr) + } + } + + exePath := appDir + "/bin/edge-httpdns" + if nodeParams.IsUpgrading { + _, err = i.client.Stat(exePath) + if err == nil { + _, _, _ = i.client.Exec(exePath + " stop") + removeErr := i.client.Remove(exePath) + if removeErr != nil && removeErr != os.ErrNotExist { + return fmt.Errorf("remove old file failed: %w", removeErr) + } + } + } + + _, stderr, err := i.client.Exec(env.HelperPath + " -cmd=unzip -zip=\"" + targetZip + "\" -target=\"" + installRootDir + "\"") + if err != nil { + return err + } + if len(stderr) > 0 { + return errors.New("unzip installer failed: " + stderr) + } + + certFile := appDir + "/configs/tls/server.crt" + keyFile := appDir + "/configs/tls/server.key" + err = i.writeTLSCertificate(certFile, keyFile, nodeParams.TLSCertData, nodeParams.TLSKeyData) + if err != nil { + installStatus.ErrorCode = "WRITE_TLS_CERT_FAILED" + return err + } + + configFile := appDir + "/configs/api_httpdns.yaml" + if i.client.sudo { + _, _, _ = i.client.Exec("chown " + i.client.User() + " " + filepath.Dir(configFile)) + } + + configData := []byte(`rpc.endpoints: [ ${endpoints} ] +nodeId: "${nodeId}" +secret: "${nodeSecret}" + +https.listenAddr: ":443" +https.cert: "${certFile}" +https.key: "${keyFile}"`) + certFileClean := strings.ReplaceAll(certFile, "\\", "/") + keyFileClean := strings.ReplaceAll(keyFile, "\\", "/") + + configData = bytes.ReplaceAll(configData, []byte("${endpoints}"), []byte(nodeParams.QuoteEndpoints())) + configData = bytes.ReplaceAll(configData, []byte("${nodeId}"), []byte(nodeParams.NodeId)) + configData = bytes.ReplaceAll(configData, []byte("${nodeSecret}"), []byte(nodeParams.Secret)) + configData = bytes.ReplaceAll(configData, []byte("${certFile}"), []byte(certFileClean)) + configData = bytes.ReplaceAll(configData, []byte("${keyFile}"), []byte(keyFileClean)) + + _, err = i.client.WriteFile(configFile, configData) + if err != nil { + 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 " + + stdout, stderr, err := i.client.Exec(startCmdPrefix + "test") + if err != nil { + installStatus.ErrorCode = "TEST_FAILED" + return fmt.Errorf("test edge-httpdns failed: %w, stdout: %s, stderr: %s", err, stdout, stderr) + } + if len(stderr) > 0 { + if regexp.MustCompile(`(?i)rpc`).MatchString(stderr) || regexp.MustCompile(`(?i)rpc`).MatchString(stdout) { + installStatus.ErrorCode = "RPC_TEST_FAILED" + } + return errors.New("test edge-httpdns failed, stdout: " + stdout + ", stderr: " + stderr) + } + + stdout, stderr, err = i.client.Exec(startCmdPrefix + "start") + if err != nil { + return fmt.Errorf("start edge-httpdns failed: %w, stdout: %s, stderr: %s", err, stdout, stderr) + } + if len(stderr) > 0 { + return errors.New("start edge-httpdns failed, stdout: " + stdout + ", stderr: " + stderr) + } + + return nil +} + +func resolveHTTPDNSInstallPaths(rawDir string) (installRootDir string, appDir string) { + dir := strings.TrimSpace(rawDir) + dir = strings.TrimRight(dir, "/") + if len(dir) == 0 { + return rawDir, rawDir + "/edge-httpdns" + } + + if strings.HasSuffix(dir, "/edge-httpdns") { + root := strings.TrimSuffix(dir, "/edge-httpdns") + if len(root) == 0 { + root = "/" + } + return root, dir + } + + return dir, dir + "/edge-httpdns" +} + +func (i *HTTPDNSNodeInstaller) copyZipToRemote(dir string, zipFile string) (string, error) { + targetZip := "" + var firstCopyErr error + zipName := filepath.Base(zipFile) + for _, candidate := range []string{ + dir + "/" + zipName, + i.client.UserHome() + "/" + zipName, + "/tmp/" + zipName, + } { + err := i.client.Copy(zipFile, candidate, 0777) + if err != nil { + if firstCopyErr == nil { + firstCopyErr = err + } + continue + } + targetZip = candidate + firstCopyErr = nil + break + } + if firstCopyErr != nil { + return "", fmt.Errorf("upload httpdns file failed: %w", firstCopyErr) + } + return targetZip, nil +} + +func (i *HTTPDNSNodeInstaller) writeTLSCertificate(certFile string, keyFile string, certData []byte, keyData []byte) error { + if len(certData) == 0 || len(keyData) == 0 { + return errors.New("cluster tls certificate is empty") + } + certDir := filepath.Dir(certFile) + _, stderr, err := i.client.Exec("mkdir -p " + shQuote(certDir)) + if err != nil { + return fmt.Errorf("create tls directory failed: %w, stderr: %s", err, stderr) + } + if i.client.sudo { + _, _, _ = i.client.Exec("chown " + i.client.User() + " " + shQuote(certDir)) + } + + _, err = i.client.WriteFile(certFile, certData) + if err != nil { + return fmt.Errorf("write cert file failed: %w", err) + } + _, err = i.client.WriteFile(keyFile, keyData) + if err != nil { + return fmt.Errorf("write key file failed: %w", err) + } + + _, stderr, err = i.client.Exec("chmod 0644 " + shQuote(certFile) + " && chmod 0600 " + shQuote(keyFile)) + if err != nil { + return fmt.Errorf("chmod tls files failed: %w, stderr: %s", err, stderr) + } + return nil +} diff --git a/EdgeAPI/internal/installers/params_node.go b/EdgeAPI/internal/installers/params_node.go index b825150..72222f4 100644 --- a/EdgeAPI/internal/installers/params_node.go +++ b/EdgeAPI/internal/installers/params_node.go @@ -9,6 +9,8 @@ type NodeParams struct { Endpoints []string NodeId string Secret string + TLSCertData []byte + TLSKeyData []byte IsUpgrading bool // 是否为升级 } diff --git a/EdgeAPI/internal/installers/queue_httpdns_node.go b/EdgeAPI/internal/installers/queue_httpdns_node.go new file mode 100644 index 0000000..0cfc743 --- /dev/null +++ b/EdgeAPI/internal/installers/queue_httpdns_node.go @@ -0,0 +1,280 @@ +package installers + +import ( + "encoding/json" + "errors" + "fmt" + "time" + + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/goman" + "github.com/TeaOSLab/EdgeAPI/internal/utils" + "github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" + "github.com/iwind/TeaGo/logs" + "github.com/iwind/TeaGo/maps" +) + +var sharedHTTPDNSNodeQueue = NewHTTPDNSNodeQueue() + +type HTTPDNSNodeQueue struct{} + +func NewHTTPDNSNodeQueue() *HTTPDNSNodeQueue { + return &HTTPDNSNodeQueue{} +} + +func SharedHTTPDNSNodeQueue() *HTTPDNSNodeQueue { + return sharedHTTPDNSNodeQueue +} + +// InstallNodeProcess 鍦ㄧ嚎瀹夎 HTTPDNS 鑺傜偣娴佺▼鎺у埗 +func (q *HTTPDNSNodeQueue) InstallNodeProcess(nodeId int64, isUpgrading bool) error { + installStatus := models.NewNodeInstallStatus() + installStatus.IsRunning = true + installStatus.IsFinished = false + installStatus.IsOk = false + installStatus.Error = "" + installStatus.ErrorCode = "" + installStatus.UpdatedAt = time.Now().Unix() + + err := models.SharedHTTPDNSNodeDAO.UpdateNodeInstallStatus(nil, nodeId, installStatus) + if err != nil { + return err + } + + ticker := utils.NewTicker(3 * time.Second) + goman.New(func() { + for ticker.Wait() { + installStatus.UpdatedAt = time.Now().Unix() + updateErr := models.SharedHTTPDNSNodeDAO.UpdateNodeInstallStatus(nil, nodeId, installStatus) + if updateErr != nil { + logs.Println("[HTTPDNS_INSTALL]" + updateErr.Error()) + } + } + }) + defer ticker.Stop() + + err = q.InstallNode(nodeId, installStatus, isUpgrading) + + installStatus.IsRunning = false + installStatus.IsFinished = true + if err != nil { + installStatus.IsOk = false + installStatus.Error = err.Error() + } else { + installStatus.IsOk = true + } + installStatus.UpdatedAt = time.Now().Unix() + + updateErr := models.SharedHTTPDNSNodeDAO.UpdateNodeInstallStatus(nil, nodeId, installStatus) + if updateErr != nil { + return updateErr + } + + if installStatus.IsOk { + return models.SharedHTTPDNSNodeDAO.UpdateNodeIsInstalled(nil, nodeId, true) + } + return nil +} + +// InstallNode 鍦ㄧ嚎瀹夎 HTTPDNS 鑺傜偣 +func (q *HTTPDNSNodeQueue) InstallNode(nodeId int64, installStatus *models.NodeInstallStatus, isUpgrading bool) error { + node, err := models.SharedHTTPDNSNodeDAO.FindEnabledNode(nil, nodeId) + if err != nil { + return err + } + if node == nil { + return errors.New("can not find node, ID '" + numberutils.FormatInt64(nodeId) + "'") + } + cluster, err := models.SharedHTTPDNSClusterDAO.FindEnabledCluster(nil, int64(node.ClusterId)) + if err != nil { + return err + } + if cluster == nil { + return errors.New("can not find cluster") + } + + sshHost, sshPort, grantId, err := q.parseSSHInfo(node) + if err != nil { + installStatus.ErrorCode = "EMPTY_SSH" + return err + } + + grant, err := models.SharedNodeGrantDAO.FindEnabledNodeGrant(nil, grantId) + if err != nil { + return err + } + if grant == nil { + installStatus.ErrorCode = "EMPTY_GRANT" + return errors.New("can not find user grant with id '" + numberutils.FormatInt64(grantId) + "'") + } + + apiNodes, err := models.SharedAPINodeDAO.FindAllEnabledAndOnAPINodes(nil) + if err != nil { + return err + } + if len(apiNodes) == 0 { + return errors.New("no available api nodes") + } + + apiEndpoints := make([]string, 0, 8) + for _, apiNode := range apiNodes { + addrConfigs, decodeErr := apiNode.DecodeAccessAddrs() + if decodeErr != nil { + return fmt.Errorf("decode api node access addresses failed: %w", decodeErr) + } + for _, addrConfig := range addrConfigs { + apiEndpoints = append(apiEndpoints, addrConfig.FullAddresses()...) + } + } + if len(apiEndpoints) == 0 { + return errors.New("no available api endpoints") + } + + tlsCertData, tlsKeyData, err := q.resolveClusterTLSCertPair(cluster) + if err != nil { + installStatus.ErrorCode = "EMPTY_TLS_CERT" + return err + } + + params := &NodeParams{ + Endpoints: apiEndpoints, + NodeId: node.UniqueId, + Secret: node.Secret, + TLSCertData: tlsCertData, + TLSKeyData: tlsKeyData, + IsUpgrading: isUpgrading, + } + + installer := &HTTPDNSNodeInstaller{} + err = installer.Login(&Credentials{ + Host: sshHost, + Port: sshPort, + Username: grant.Username, + Password: grant.Password, + PrivateKey: grant.PrivateKey, + Passphrase: grant.Passphrase, + Method: grant.Method, + Sudo: grant.Su == 1, + }) + if err != nil { + installStatus.ErrorCode = "SSH_LOGIN_FAILED" + return err + } + defer func() { + _ = installer.Close() + }() + + installDir := node.InstallDir + if len(installDir) == 0 { + if cluster != nil && len(cluster.InstallDir) > 0 { + installDir = cluster.InstallDir + } + if len(installDir) == 0 { + installDir = installer.client.UserHome() + "/edge-httpdns" + } + } + + return installer.Install(installDir, params, installStatus) +} + +func (q *HTTPDNSNodeQueue) resolveClusterTLSCertPair(cluster *models.HTTPDNSCluster) ([]byte, []byte, error) { + if cluster == nil { + return nil, nil, errors.New("cluster not found") + } + if len(cluster.TLSPolicy) == 0 { + return nil, nil, errors.New("cluster tls policy is empty") + } + + tlsConfig := map[string]json.RawMessage{} + if err := json.Unmarshal(cluster.TLSPolicy, &tlsConfig); err != nil { + return nil, nil, fmt.Errorf("decode cluster tls policy failed: %w", err) + } + + sslPolicyData := tlsConfig["sslPolicy"] + if len(sslPolicyData) == 0 { + // Compatible with old data where TLSPolicy stores SSLPolicy directly. + sslPolicyData = json.RawMessage(cluster.TLSPolicy) + } + sslPolicy := &sslconfigs.SSLPolicy{} + if err := json.Unmarshal(sslPolicyData, sslPolicy); err != nil { + return nil, nil, fmt.Errorf("decode ssl policy failed: %w", err) + } + + for _, cert := range sslPolicy.Certs { + if cert == nil { + continue + } + if len(cert.CertData) > 0 && len(cert.KeyData) > 0 { + return cert.CertData, cert.KeyData, nil + } + } + + for _, certRef := range sslPolicy.CertRefs { + if certRef == nil || certRef.CertId <= 0 { + continue + } + certConfig, err := models.SharedSSLCertDAO.ComposeCertConfig(nil, certRef.CertId, false, nil, nil) + if err != nil { + return nil, nil, fmt.Errorf("load ssl cert %d failed: %w", certRef.CertId, err) + } + if certConfig == nil { + continue + } + if len(certConfig.CertData) > 0 && len(certConfig.KeyData) > 0 { + return certConfig.CertData, certConfig.KeyData, nil + } + } + + if sslPolicy.Id > 0 { + policyConfig, err := models.SharedSSLPolicyDAO.ComposePolicyConfig(nil, sslPolicy.Id, false, nil, nil) + if err != nil { + return nil, nil, fmt.Errorf("load ssl policy %d failed: %w", sslPolicy.Id, err) + } + if policyConfig != nil { + for _, cert := range policyConfig.Certs { + if cert == nil { + continue + } + if len(cert.CertData) > 0 && len(cert.KeyData) > 0 { + return cert.CertData, cert.KeyData, nil + } + } + } + } + + return nil, nil, errors.New("cluster tls certificate is not configured") +} + +func (q *HTTPDNSNodeQueue) parseSSHInfo(node *models.HTTPDNSNode) (string, int, int64, error) { + if node == nil { + return "", 0, 0, errors.New("node should not be nil") + } + if len(node.InstallStatus) == 0 { + return "", 0, 0, errors.New("ssh config should not be empty") + } + + statusMap := maps.Map{} + err := json.Unmarshal(node.InstallStatus, &statusMap) + if err != nil { + return "", 0, 0, errors.New("invalid install status data") + } + sshMap := statusMap.GetMap("ssh") + if sshMap == nil { + return "", 0, 0, errors.New("ssh config should not be empty") + } + + host := sshMap.GetString("host") + port := sshMap.GetInt("port") + grantId := sshMap.GetInt64("grantId") + if len(host) == 0 { + return "", 0, 0, errors.New("ssh host should not be empty") + } + if port <= 0 { + port = 22 + } + if grantId <= 0 { + return "", 0, 0, errors.New("grant id should not be empty") + } + return host, port, grantId, nil +} diff --git a/EdgeAPI/internal/nodes/api_node.go b/EdgeAPI/internal/nodes/api_node.go index c9ea2fc..e6b05e3 100644 --- a/EdgeAPI/internal/nodes/api_node.go +++ b/EdgeAPI/internal/nodes/api_node.go @@ -144,6 +144,17 @@ func (this *APINode) Start() { this.processTableNames() dbs.NotifyReady() + // 自动确保 ClickHouse 日志表存在(不阻断主流程) + this.setProgress("CLICKHOUSE", "正在检查 ClickHouse 日志表") + logs.Println("[API_NODE]ensuring clickhouse tables ...") + err = setup.EnsureClickHouseTables() + if err != nil { + logs.Println("[API_NODE]WARNING: ensure clickhouse tables failed: " + err.Error()) + remotelogs.Error("API_NODE", "ensure clickhouse tables failed: "+err.Error()) + } else { + logs.Println("[API_NODE]ensure clickhouse tables done") + } + // 设置时区 this.setProgress("TIMEZONE", "正在设置时区") this.setupTimeZone() diff --git a/EdgeAPI/internal/nodes/api_node_services.go b/EdgeAPI/internal/nodes/api_node_services.go index be28ac3..b7df91a 100644 --- a/EdgeAPI/internal/nodes/api_node_services.go +++ b/EdgeAPI/internal/nodes/api_node_services.go @@ -5,6 +5,7 @@ package nodes import ( "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" "github.com/TeaOSLab/EdgeAPI/internal/rpc/services/clients" + httpdnsservices "github.com/TeaOSLab/EdgeAPI/internal/rpc/services/httpdns" "github.com/TeaOSLab/EdgeAPI/internal/rpc/services/users" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "google.golang.org/grpc" @@ -425,6 +426,46 @@ func (this *APINode) registerServices(server *grpc.Server) { pb.RegisterDNSTaskServiceServer(server, instance) this.rest(instance) } + { + var instance = this.serviceInstance(&httpdnsservices.HTTPDNSClusterService{}).(*httpdnsservices.HTTPDNSClusterService) + pb.RegisterHTTPDNSClusterServiceServer(server, instance) + this.rest(instance) + } + { + var instance = this.serviceInstance(&httpdnsservices.HTTPDNSNodeService{}).(*httpdnsservices.HTTPDNSNodeService) + pb.RegisterHTTPDNSNodeServiceServer(server, instance) + this.rest(instance) + } + { + var instance = this.serviceInstance(&httpdnsservices.HTTPDNSAppService{}).(*httpdnsservices.HTTPDNSAppService) + pb.RegisterHTTPDNSAppServiceServer(server, instance) + this.rest(instance) + } + { + var instance = this.serviceInstance(&httpdnsservices.HTTPDNSDomainService{}).(*httpdnsservices.HTTPDNSDomainService) + pb.RegisterHTTPDNSDomainServiceServer(server, instance) + this.rest(instance) + } + { + var instance = this.serviceInstance(&httpdnsservices.HTTPDNSRuleService{}).(*httpdnsservices.HTTPDNSRuleService) + pb.RegisterHTTPDNSRuleServiceServer(server, instance) + this.rest(instance) + } + { + var instance = this.serviceInstance(&httpdnsservices.HTTPDNSAccessLogService{}).(*httpdnsservices.HTTPDNSAccessLogService) + pb.RegisterHTTPDNSAccessLogServiceServer(server, instance) + this.rest(instance) + } + { + var instance = this.serviceInstance(&httpdnsservices.HTTPDNSRuntimeLogService{}).(*httpdnsservices.HTTPDNSRuntimeLogService) + pb.RegisterHTTPDNSRuntimeLogServiceServer(server, instance) + this.rest(instance) + } + { + var instance = this.serviceInstance(&httpdnsservices.HTTPDNSSandboxService{}).(*httpdnsservices.HTTPDNSSandboxService) + pb.RegisterHTTPDNSSandboxServiceServer(server, instance) + this.rest(instance) + } { var instance = this.serviceInstance(&services.NodeClusterFirewallActionService{}).(*services.NodeClusterFirewallActionService) pb.RegisterNodeClusterFirewallActionServiceServer(server, instance) diff --git a/EdgeAPI/internal/rpc/services/httpdns/converters.go b/EdgeAPI/internal/rpc/services/httpdns/converters.go new file mode 100644 index 0000000..cd57a78 --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/converters.go @@ -0,0 +1,125 @@ +package httpdns + +import ( + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" +) + +func toPBCluster(cluster *models.HTTPDNSCluster) *pb.HTTPDNSCluster { + if cluster == nil { + return nil + } + return &pb.HTTPDNSCluster{ + Id: int64(cluster.Id), + IsOn: cluster.IsOn, + IsDefault: cluster.IsDefault, + Name: cluster.Name, + ServiceDomain: cluster.ServiceDomain, + DefaultTTL: cluster.DefaultTTL, + FallbackTimeoutMs: cluster.FallbackTimeoutMs, + InstallDir: cluster.InstallDir, + TlsPolicyJSON: cluster.TLSPolicy, + CreatedAt: int64(cluster.CreatedAt), + UpdatedAt: int64(cluster.UpdatedAt), + } +} + +func toPBNode(node *models.HTTPDNSNode) *pb.HTTPDNSNode { + if node == nil { + return nil + } + return &pb.HTTPDNSNode{ + Id: int64(node.Id), + ClusterId: int64(node.ClusterId), + Name: node.Name, + IsOn: node.IsOn, + IsUp: node.IsUp, + IsInstalled: node.IsInstalled, + IsActive: node.IsActive, + UniqueId: node.UniqueId, + Secret: node.Secret, + InstallDir: node.InstallDir, + StatusJSON: node.Status, + InstallStatusJSON: node.InstallStatus, + CreatedAt: int64(node.CreatedAt), + UpdatedAt: int64(node.UpdatedAt), + } +} + +func toPBApp(app *models.HTTPDNSApp, secret *models.HTTPDNSAppSecret) *pb.HTTPDNSApp { + if app == nil { + return nil + } + var signEnabled bool + var signSecret string + var signUpdatedAt int64 + if secret != nil { + signEnabled = secret.SignEnabled + signSecret = secret.SignSecret + signUpdatedAt = int64(secret.SignUpdatedAt) + } + return &pb.HTTPDNSApp{ + Id: int64(app.Id), + Name: app.Name, + AppId: app.AppId, + IsOn: app.IsOn, + PrimaryClusterId: int64(app.PrimaryClusterId), + BackupClusterId: int64(app.BackupClusterId), + SniMode: app.SNIMode, + SignEnabled: signEnabled, + SignSecret: signSecret, + SignUpdatedAt: signUpdatedAt, + CreatedAt: int64(app.CreatedAt), + UpdatedAt: int64(app.UpdatedAt), + UserId: int64(app.UserId), + } +} + +func toPBDomain(domain *models.HTTPDNSDomain, ruleCount int64) *pb.HTTPDNSDomain { + if domain == nil { + return nil + } + return &pb.HTTPDNSDomain{ + Id: int64(domain.Id), + AppId: int64(domain.AppId), + Domain: domain.Domain, + IsOn: domain.IsOn, + CreatedAt: int64(domain.CreatedAt), + UpdatedAt: int64(domain.UpdatedAt), + RuleCount: ruleCount, + } +} + +func toPBRule(rule *models.HTTPDNSCustomRule, records []*models.HTTPDNSCustomRuleRecord) *pb.HTTPDNSCustomRule { + if rule == nil { + return nil + } + var pbRecords []*pb.HTTPDNSRuleRecord + for _, record := range records { + pbRecords = append(pbRecords, &pb.HTTPDNSRuleRecord{ + Id: int64(record.Id), + RuleId: int64(record.RuleId), + RecordType: record.RecordType, + RecordValue: record.RecordValue, + Weight: record.Weight, + Sort: record.Sort, + }) + } + return &pb.HTTPDNSCustomRule{ + Id: int64(rule.Id), + AppId: int64(rule.AppId), + DomainId: int64(rule.DomainId), + RuleName: rule.RuleName, + LineScope: rule.LineScope, + LineCarrier: rule.LineCarrier, + LineRegion: rule.LineRegion, + LineProvince: rule.LineProvince, + LineContinent: rule.LineContinent, + LineCountry: rule.LineCountry, + Ttl: rule.TTL, + IsOn: rule.IsOn, + Priority: rule.Priority, + UpdatedAt: int64(rule.UpdatedAt), + Records: pbRecords, + } +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log.go new file mode 100644 index 0000000..6a415ef --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log.go @@ -0,0 +1,258 @@ +package httpdns + +import ( + "context" + "log" + "strconv" + "time" + + "github.com/TeaOSLab/EdgeAPI/internal/clickhouse" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + timeutil "github.com/iwind/TeaGo/utils/time" +) + +type HTTPDNSAccessLogService struct { + services.BaseService + pb.UnimplementedHTTPDNSAccessLogServiceServer +} + +func (s *HTTPDNSAccessLogService) CreateHTTPDNSAccessLogs(ctx context.Context, req *pb.CreateHTTPDNSAccessLogsRequest) (*pb.CreateHTTPDNSAccessLogsResponse, error) { + nodeIdInContext, err := s.ValidateHTTPDNSNode(ctx) + if err != nil { + _, err = s.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + } + + if len(req.GetLogs()) == 0 { + return &pb.CreateHTTPDNSAccessLogsResponse{}, nil + } + + mysqlLogs := make([]*models.HTTPDNSAccessLog, 0, len(req.GetLogs())) + chLogs := make([]*pb.HTTPDNSAccessLog, 0, len(req.GetLogs())) + seen := map[string]struct{}{} + for _, item := range req.GetLogs() { + if item == nil { + continue + } + nodeId := item.GetNodeId() + // When called by HTTPDNS node, trust node id parsed from RPC token. + if nodeIdInContext > 0 { + nodeId = nodeIdInContext + } + clusterId := item.GetClusterId() + if clusterId <= 0 && nodeId > 0 { + clusterId, _ = models.SharedHTTPDNSNodeDAO.FindNodeClusterId(s.NullTx(), nodeId) + } + + key := item.GetRequestId() + "#" + strconv.FormatInt(nodeId, 10) + if _, ok := seen[key]; ok { + continue + } + seen[key] = struct{}{} + + createdAt := item.GetCreatedAt() + if createdAt <= 0 { + createdAt = time.Now().Unix() + } + day := item.GetDay() + if len(day) == 0 { + day = timeutil.Format("Ymd") + } + + mysqlLogs = append(mysqlLogs, &models.HTTPDNSAccessLog{ + RequestId: item.GetRequestId(), + ClusterId: uint32(clusterId), + NodeId: uint32(nodeId), + AppId: item.GetAppId(), + AppName: item.GetAppName(), + Domain: item.GetDomain(), + QType: item.GetQtype(), + ClientIP: item.GetClientIP(), + ClientRegion: item.GetClientRegion(), + Carrier: item.GetCarrier(), + SDKVersion: item.GetSdkVersion(), + OS: item.GetOs(), + ResultIPs: item.GetResultIPs(), + Status: item.GetStatus(), + ErrorCode: item.GetErrorCode(), + CostMs: item.GetCostMs(), + CreatedAt: uint64(createdAt), + Day: day, + Summary: item.GetSummary(), + }) + + chLogs = append(chLogs, &pb.HTTPDNSAccessLog{ + RequestId: item.GetRequestId(), + ClusterId: clusterId, + NodeId: nodeId, + AppId: item.GetAppId(), + AppName: item.GetAppName(), + Domain: item.GetDomain(), + Qtype: item.GetQtype(), + ClientIP: item.GetClientIP(), + ClientRegion: item.GetClientRegion(), + Carrier: item.GetCarrier(), + SdkVersion: item.GetSdkVersion(), + Os: item.GetOs(), + ResultIPs: item.GetResultIPs(), + Status: item.GetStatus(), + ErrorCode: item.GetErrorCode(), + CostMs: item.GetCostMs(), + CreatedAt: createdAt, + Day: day, + Summary: item.GetSummary(), + }) + } + + if s.canWriteHTTPDNSAccessLogsToMySQL() { + for _, item := range mysqlLogs { + err = models.SharedHTTPDNSAccessLogDAO.CreateLog(s.NullTx(), item) + if err != nil { + if models.CheckSQLDuplicateErr(err) { + continue + } + return nil, err + } + } + } + + store := clickhouse.NewHTTPDNSAccessLogsStore() + if s.canWriteHTTPDNSAccessLogsToClickHouse() && store.Client().IsConfigured() && len(chLogs) > 0 { + err = store.Insert(ctx, chLogs) + if err != nil { + log.Println("[HTTPDNS_ACCESS_LOG]write clickhouse failed, keep mysql success:", err.Error()) + } + } + + return &pb.CreateHTTPDNSAccessLogsResponse{}, nil +} + +func (s *HTTPDNSAccessLogService) ListHTTPDNSAccessLogs(ctx context.Context, req *pb.ListHTTPDNSAccessLogsRequest) (*pb.ListHTTPDNSAccessLogsResponse, error) { + _, _, err := s.ValidateAdminAndUser(ctx, true) + if err != nil { + return nil, err + } + + store := clickhouse.NewHTTPDNSAccessLogsStore() + canReadFromClickHouse := s.shouldReadHTTPDNSAccessLogsFromClickHouse() && store.Client().IsConfigured() + canReadFromMySQL := s.shouldReadHTTPDNSAccessLogsFromMySQL() + if canReadFromClickHouse { + resp, listErr := s.listFromClickHouse(ctx, store, req) + if listErr == nil { + return resp, nil + } + log.Println("[HTTPDNS_ACCESS_LOG]read clickhouse failed, fallback mysql:", listErr.Error()) + if !canReadFromMySQL { + return nil, listErr + } + } + + if !canReadFromMySQL { + return &pb.ListHTTPDNSAccessLogsResponse{ + Logs: []*pb.HTTPDNSAccessLog{}, + Total: 0, + }, nil + } + + total, err := models.SharedHTTPDNSAccessLogDAO.CountLogs(s.NullTx(), req.GetDay(), req.GetClusterId(), req.GetNodeId(), req.GetAppId(), req.GetDomain(), req.GetStatus(), req.GetKeyword()) + if err != nil { + return nil, err + } + logs, err := models.SharedHTTPDNSAccessLogDAO.ListLogs(s.NullTx(), req.GetDay(), req.GetClusterId(), req.GetNodeId(), req.GetAppId(), req.GetDomain(), req.GetStatus(), req.GetKeyword(), req.GetOffset(), req.GetSize()) + if err != nil { + return nil, err + } + + result := make([]*pb.HTTPDNSAccessLog, 0, len(logs)) + for _, item := range logs { + if item == nil { + continue + } + + clusterName, _ := models.SharedHTTPDNSClusterDAO.FindEnabledClusterName(s.NullTx(), int64(item.ClusterId)) + nodeName := "" + node, _ := models.SharedHTTPDNSNodeDAO.FindEnabledNode(s.NullTx(), int64(item.NodeId)) + if node != nil { + nodeName = node.Name + } + + result = append(result, &pb.HTTPDNSAccessLog{ + Id: int64(item.Id), + RequestId: item.RequestId, + ClusterId: int64(item.ClusterId), + NodeId: int64(item.NodeId), + AppId: item.AppId, + AppName: item.AppName, + Domain: item.Domain, + Qtype: item.QType, + ClientIP: item.ClientIP, + ClientRegion: item.ClientRegion, + Carrier: item.Carrier, + SdkVersion: item.SDKVersion, + Os: item.OS, + ResultIPs: item.ResultIPs, + Status: item.Status, + ErrorCode: item.ErrorCode, + CostMs: item.CostMs, + CreatedAt: int64(item.CreatedAt), + Day: item.Day, + Summary: item.Summary, + NodeName: nodeName, + ClusterName: clusterName, + }) + } + + return &pb.ListHTTPDNSAccessLogsResponse{ + Logs: result, + Total: total, + }, nil +} + +func (s *HTTPDNSAccessLogService) listFromClickHouse(ctx context.Context, store *clickhouse.HTTPDNSAccessLogsStore, req *pb.ListHTTPDNSAccessLogsRequest) (*pb.ListHTTPDNSAccessLogsResponse, error) { + filter := clickhouse.HTTPDNSAccessLogListFilter{ + Day: req.GetDay(), + ClusterId: req.GetClusterId(), + NodeId: req.GetNodeId(), + AppId: req.GetAppId(), + Domain: req.GetDomain(), + Status: req.GetStatus(), + Keyword: req.GetKeyword(), + Offset: req.GetOffset(), + Size: req.GetSize(), + } + + total, err := store.Count(ctx, filter) + if err != nil { + return nil, err + } + rows, err := store.List(ctx, filter) + if err != nil { + return nil, err + } + + result := make([]*pb.HTTPDNSAccessLog, 0, len(rows)) + for _, row := range rows { + item := clickhouse.HTTPDNSRowToPB(row) + if item == nil { + continue + } + clusterName, _ := models.SharedHTTPDNSClusterDAO.FindEnabledClusterName(s.NullTx(), item.GetClusterId()) + nodeName := "" + node, _ := models.SharedHTTPDNSNodeDAO.FindEnabledNode(s.NullTx(), item.GetNodeId()) + if node != nil { + nodeName = node.Name + } + item.ClusterName = clusterName + item.NodeName = nodeName + result = append(result, item) + } + + return &pb.ListHTTPDNSAccessLogsResponse{ + Logs: result, + Total: total, + }, nil +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log_ext.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log_ext.go new file mode 100644 index 0000000..8a2c01d --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log_ext.go @@ -0,0 +1,19 @@ +//go:build !plus + +package httpdns + +func (s *HTTPDNSAccessLogService) canWriteHTTPDNSAccessLogsToMySQL() bool { + return true +} + +func (s *HTTPDNSAccessLogService) canWriteHTTPDNSAccessLogsToClickHouse() bool { + return true +} + +func (s *HTTPDNSAccessLogService) shouldReadHTTPDNSAccessLogsFromClickHouse() bool { + return true +} + +func (s *HTTPDNSAccessLogService) shouldReadHTTPDNSAccessLogsFromMySQL() bool { + return true +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log_ext_plus.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log_ext_plus.go new file mode 100644 index 0000000..cda9276 --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_access_log_ext_plus.go @@ -0,0 +1,124 @@ +//go:build plus + +package httpdns + +import ( + "log" + "sync" + "time" + + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" +) + +var ( + httpDNSAccessLogWriteTargetsLocker sync.RWMutex + httpDNSAccessLogWriteTargetsCache = &serverconfigs.AccessLogWriteTargets{ + File: true, + MySQL: true, + ClickHouse: false, + } + httpDNSAccessLogWriteTargetsExpireAt int64 +) + +const httpDNSAccessLogWriteTargetsCacheTTL = 10 * time.Second + +func (s *HTTPDNSAccessLogService) canWriteHTTPDNSAccessLogsToMySQL() bool { + targets := s.readHTTPDNSAccessLogWriteTargets() + if targets == nil { + return true + } + return targets.MySQL +} + +func (s *HTTPDNSAccessLogService) canWriteHTTPDNSAccessLogsToClickHouse() bool { + targets := s.readHTTPDNSAccessLogWriteTargets() + if targets == nil { + return false + } + return targets.ClickHouse +} + +func (s *HTTPDNSAccessLogService) shouldReadHTTPDNSAccessLogsFromClickHouse() bool { + targets := s.readHTTPDNSAccessLogWriteTargets() + if targets == nil { + return false + } + return targets.ClickHouse +} + +func (s *HTTPDNSAccessLogService) shouldReadHTTPDNSAccessLogsFromMySQL() bool { + targets := s.readHTTPDNSAccessLogWriteTargets() + if targets == nil { + return true + } + return targets.MySQL +} + +func (s *HTTPDNSAccessLogService) readHTTPDNSAccessLogWriteTargets() *serverconfigs.AccessLogWriteTargets { + now := time.Now().Unix() + + httpDNSAccessLogWriteTargetsLocker.RLock() + if now < httpDNSAccessLogWriteTargetsExpireAt && httpDNSAccessLogWriteTargetsCache != nil { + targets := *httpDNSAccessLogWriteTargetsCache + httpDNSAccessLogWriteTargetsLocker.RUnlock() + return &targets + } + httpDNSAccessLogWriteTargetsLocker.RUnlock() + + httpDNSAccessLogWriteTargetsLocker.Lock() + defer httpDNSAccessLogWriteTargetsLocker.Unlock() + + // double-check + now = time.Now().Unix() + if now < httpDNSAccessLogWriteTargetsExpireAt && httpDNSAccessLogWriteTargetsCache != nil { + targets := *httpDNSAccessLogWriteTargetsCache + return &targets + } + + targets := s.loadHTTPDNSAccessLogWriteTargetsFromPolicy() + if targets == nil { + targets = &serverconfigs.AccessLogWriteTargets{ + File: true, + MySQL: true, + ClickHouse: false, + } + } + + httpDNSAccessLogWriteTargetsCache = targets + httpDNSAccessLogWriteTargetsExpireAt = time.Now().Add(httpDNSAccessLogWriteTargetsCacheTTL).Unix() + + copyTargets := *targets + return ©Targets +} + +func (s *HTTPDNSAccessLogService) loadHTTPDNSAccessLogWriteTargetsFromPolicy() *serverconfigs.AccessLogWriteTargets { + tx := s.NullTx() + publicPolicyId, err := models.SharedHTTPAccessLogPolicyDAO.FindCurrentPublicPolicyId(tx) + if err != nil { + log.Println("[HTTPDNS_ACCESS_LOG]load public access log policy failed:", err.Error()) + return nil + } + if publicPolicyId <= 0 { + return &serverconfigs.AccessLogWriteTargets{ + File: true, + MySQL: true, + ClickHouse: false, + } + } + + policy, err := models.SharedHTTPAccessLogPolicyDAO.FindEnabledHTTPAccessLogPolicy(tx, publicPolicyId) + if err != nil { + log.Println("[HTTPDNS_ACCESS_LOG]load access log policy detail failed:", err.Error()) + return nil + } + if policy == nil { + return &serverconfigs.AccessLogWriteTargets{ + File: true, + MySQL: true, + ClickHouse: false, + } + } + + return serverconfigs.ParseWriteTargetsFromPolicy(policy.WriteTargets, policy.Type, policy.DisableDefaultDB) +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_app.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_app.go new file mode 100644 index 0000000..41c238e --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_app.go @@ -0,0 +1,246 @@ +package httpdns + +import ( + "context" + "errors" + "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/dbs" + "strings" + + "github.com/TeaOSLab/EdgeAPI/internal/db/models" +) + +// HTTPDNSAppService HTTPDNS应用服务 +type HTTPDNSAppService struct { + services.BaseService + pb.UnimplementedHTTPDNSAppServiceServer +} + +func (this *HTTPDNSAppService) CreateHTTPDNSApp(ctx context.Context, req *pb.CreateHTTPDNSAppRequest) (*pb.CreateHTTPDNSAppResponse, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + if len(req.Name) == 0 || len(req.AppId) == 0 { + return nil, errors.New("required 'name' and 'appId'") + } + if req.PrimaryClusterId <= 0 { + return nil, errors.New("required 'primaryClusterId'") + } + var appDbId int64 + err = this.RunTx(func(tx *dbs.Tx) error { + exists, err := models.SharedHTTPDNSAppDAO.FindEnabledAppWithAppId(tx, strings.TrimSpace(req.AppId)) + if err != nil { + return err + } + if exists != nil { + return errors.New("appId already exists") + } + + appDbId, err = models.SharedHTTPDNSAppDAO.CreateApp(tx, req.Name, strings.TrimSpace(req.AppId), req.PrimaryClusterId, req.BackupClusterId, req.IsOn, req.UserId) + if err != nil { + return err + } + _, _, err = models.SharedHTTPDNSAppSecretDAO.InitAppSecret(tx, appDbId, req.SignEnabled) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, appDbId, models.HTTPDNSNodeTaskTypeAppChanged) + }) + if err != nil { + return nil, err + } + return &pb.CreateHTTPDNSAppResponse{AppDbId: appDbId}, nil +} + +func (this *HTTPDNSAppService) UpdateHTTPDNSApp(ctx context.Context, req *pb.UpdateHTTPDNSAppRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + oldApp, err := models.SharedHTTPDNSAppDAO.FindEnabledApp(tx, req.AppDbId) + if err != nil { + return err + } + if oldApp == nil { + return errors.New("app not found") + } + + err = models.SharedHTTPDNSAppDAO.UpdateApp(tx, req.AppDbId, req.Name, req.PrimaryClusterId, req.BackupClusterId, req.IsOn, req.UserId) + if err != nil { + return err + } + + err = notifyHTTPDNSAppTasksByApp(tx, oldApp, models.HTTPDNSNodeTaskTypeAppChanged) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, req.AppDbId, models.HTTPDNSNodeTaskTypeAppChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSAppService) DeleteHTTPDNSApp(ctx context.Context, req *pb.DeleteHTTPDNSAppRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + app, err := models.SharedHTTPDNSAppDAO.FindEnabledApp(tx, req.AppDbId) + if err != nil { + return err + } + if app == nil { + return nil + } + + // 1) 先停用规则记录 + rules, err := models.SharedHTTPDNSCustomRuleDAO.ListEnabledRulesWithAppId(tx, req.AppDbId) + if err != nil { + return err + } + for _, rule := range rules { + err = models.SharedHTTPDNSCustomRuleRecordDAO.DisableRecordsWithRuleId(tx, int64(rule.Id)) + if err != nil { + return err + } + } + + // 2) 停用规则、域名、密钥 + err = models.SharedHTTPDNSCustomRuleDAO.DisableRulesWithAppId(tx, req.AppDbId) + if err != nil { + return err + } + err = models.SharedHTTPDNSDomainDAO.DisableDomainsWithAppId(tx, req.AppDbId) + if err != nil { + return err + } + err = models.SharedHTTPDNSAppSecretDAO.DisableAppSecret(tx, req.AppDbId) + if err != nil { + return err + } + + // 3) 删除该应用的 MySQL 访问日志,避免残留 + err = models.SharedHTTPDNSAccessLogDAO.DeleteLogsWithAppId(tx, app.AppId) + if err != nil { + return err + } + + // 4) 最后停用应用 + err = models.SharedHTTPDNSAppDAO.DisableApp(tx, req.AppDbId) + if err != nil { + return err + } + + return notifyHTTPDNSAppTasksByApp(tx, app, models.HTTPDNSNodeTaskTypeAppChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSAppService) FindHTTPDNSApp(ctx context.Context, req *pb.FindHTTPDNSAppRequest) (*pb.FindHTTPDNSAppResponse, error) { + _, _, err := this.ValidateAdminAndUser(ctx, true) + if err != nil { + return nil, err + } + app, err := models.SharedHTTPDNSAppDAO.FindEnabledApp(this.NullTx(), req.AppDbId) + if err != nil { + return nil, err + } + secret, err := models.SharedHTTPDNSAppSecretDAO.FindEnabledAppSecret(this.NullTx(), req.AppDbId) + if err != nil { + return nil, err + } + return &pb.FindHTTPDNSAppResponse{App: toPBApp(app, secret)}, nil +} + +func (this *HTTPDNSAppService) ListHTTPDNSApps(ctx context.Context, req *pb.ListHTTPDNSAppsRequest) (*pb.ListHTTPDNSAppsResponse, error) { + _, _, err := this.ValidateAdminAndUser(ctx, true) + if err != nil { + return nil, err + } + apps, err := models.SharedHTTPDNSAppDAO.ListEnabledApps(this.NullTx(), req.Offset, req.Size, req.Keyword) + if err != nil { + return nil, err + } + var pbApps []*pb.HTTPDNSApp + for _, app := range apps { + secret, err := models.SharedHTTPDNSAppSecretDAO.FindEnabledAppSecret(this.NullTx(), int64(app.Id)) + if err != nil { + return nil, err + } + pbApps = append(pbApps, toPBApp(app, secret)) + } + return &pb.ListHTTPDNSAppsResponse{Apps: pbApps}, nil +} + +func (this *HTTPDNSAppService) FindAllHTTPDNSApps(ctx context.Context, req *pb.FindAllHTTPDNSAppsRequest) (*pb.FindAllHTTPDNSAppsResponse, error) { + _, _, validateErr := this.ValidateAdminAndUser(ctx, true) + if validateErr != nil { + if _, nodeErr := this.ValidateHTTPDNSNode(ctx); nodeErr != nil { + return nil, validateErr + } + } + apps, err := models.SharedHTTPDNSAppDAO.FindAllEnabledApps(this.NullTx()) + if err != nil { + return nil, err + } + var pbApps []*pb.HTTPDNSApp + for _, app := range apps { + secret, err := models.SharedHTTPDNSAppSecretDAO.FindEnabledAppSecret(this.NullTx(), int64(app.Id)) + if err != nil { + return nil, err + } + pbApps = append(pbApps, toPBApp(app, secret)) + } + return &pb.FindAllHTTPDNSAppsResponse{Apps: pbApps}, nil +} + +func (this *HTTPDNSAppService) UpdateHTTPDNSAppSignEnabled(ctx context.Context, req *pb.UpdateHTTPDNSAppSignEnabledRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + err := models.SharedHTTPDNSAppSecretDAO.UpdateSignEnabled(tx, req.AppDbId, req.SignEnabled) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, req.AppDbId, models.HTTPDNSNodeTaskTypeAppChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSAppService) ResetHTTPDNSAppSignSecret(ctx context.Context, req *pb.ResetHTTPDNSAppSignSecretRequest) (*pb.ResetHTTPDNSAppSignSecretResponse, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + var signSecret string + var updatedAt int64 + err = this.RunTx(func(tx *dbs.Tx) error { + var err error + signSecret, updatedAt, err = models.SharedHTTPDNSAppSecretDAO.ResetSignSecret(tx, req.AppDbId) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, req.AppDbId, models.HTTPDNSNodeTaskTypeAppChanged) + }) + if err != nil { + return nil, err + } + return &pb.ResetHTTPDNSAppSignSecretResponse{ + SignSecret: signSecret, + UpdatedAt: updatedAt, + }, nil +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_cluster.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_cluster.go new file mode 100644 index 0000000..fda859d --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_cluster.go @@ -0,0 +1,170 @@ +package httpdns + +import ( + "context" + "errors" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/dbs" +) + +// HTTPDNSClusterService HTTPDNS集群服务 +type HTTPDNSClusterService struct { + services.BaseService + pb.UnimplementedHTTPDNSClusterServiceServer +} + +func (this *HTTPDNSClusterService) CreateHTTPDNSCluster(ctx context.Context, req *pb.CreateHTTPDNSClusterRequest) (*pb.CreateHTTPDNSClusterResponse, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + if len(req.Name) == 0 { + return nil, errors.New("required 'name'") + } + var clusterId int64 + err = this.RunTx(func(tx *dbs.Tx) error { + clusterId, err = models.SharedHTTPDNSClusterDAO.CreateCluster(tx, req.Name, req.ServiceDomain, req.DefaultTTL, req.FallbackTimeoutMs, req.InstallDir, req.TlsPolicyJSON, req.IsOn, req.IsDefault) + if err != nil { + return err + } + return notifyHTTPDNSClusterTask(tx, clusterId, models.HTTPDNSNodeTaskTypeConfigChanged) + }) + if err != nil { + return nil, err + } + return &pb.CreateHTTPDNSClusterResponse{ClusterId: clusterId}, nil +} + +func (this *HTTPDNSClusterService) UpdateHTTPDNSCluster(ctx context.Context, req *pb.UpdateHTTPDNSClusterRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + err = models.SharedHTTPDNSClusterDAO.UpdateCluster(tx, req.ClusterId, req.Name, req.ServiceDomain, req.DefaultTTL, req.FallbackTimeoutMs, req.InstallDir, req.TlsPolicyJSON, req.IsOn, req.IsDefault) + if err != nil { + return err + } + taskType := models.HTTPDNSNodeTaskTypeConfigChanged + if len(req.TlsPolicyJSON) > 0 { + taskType = models.HTTPDNSNodeTaskTypeTLSChanged + } + return notifyHTTPDNSClusterTask(tx, req.ClusterId, taskType) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSClusterService) DeleteHTTPDNSCluster(ctx context.Context, req *pb.DeleteHTTPDNSClusterRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + err = models.SharedHTTPDNSClusterDAO.DisableCluster(tx, req.ClusterId) + if err != nil { + return err + } + return notifyHTTPDNSClusterTask(tx, req.ClusterId, models.HTTPDNSNodeTaskTypeConfigChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSClusterService) FindHTTPDNSCluster(ctx context.Context, req *pb.FindHTTPDNSClusterRequest) (*pb.FindHTTPDNSClusterResponse, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + cluster, err := models.SharedHTTPDNSClusterDAO.FindEnabledCluster(this.NullTx(), req.ClusterId) + if err != nil { + return nil, err + } + return &pb.FindHTTPDNSClusterResponse{Cluster: toPBCluster(cluster)}, nil +} + +func (this *HTTPDNSClusterService) ListHTTPDNSClusters(ctx context.Context, req *pb.ListHTTPDNSClustersRequest) (*pb.ListHTTPDNSClustersResponse, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + clusters, err := models.SharedHTTPDNSClusterDAO.ListEnabledClusters(this.NullTx(), req.Offset, req.Size, req.Keyword) + if err != nil { + return nil, err + } + var pbClusters []*pb.HTTPDNSCluster + for _, cluster := range clusters { + pbClusters = append(pbClusters, toPBCluster(cluster)) + } + return &pb.ListHTTPDNSClustersResponse{Clusters: pbClusters}, nil +} + +func (this *HTTPDNSClusterService) FindAllHTTPDNSClusters(ctx context.Context, req *pb.FindAllHTTPDNSClustersRequest) (*pb.FindAllHTTPDNSClustersResponse, error) { + _, _, validateErr := this.ValidateAdminAndUser(ctx, true) + if validateErr != nil { + if _, nodeErr := this.ValidateHTTPDNSNode(ctx); nodeErr != nil { + return nil, validateErr + } + } + clusters, err := models.SharedHTTPDNSClusterDAO.FindAllEnabledClusters(this.NullTx()) + if err != nil { + return nil, err + } + var pbClusters []*pb.HTTPDNSCluster + for _, cluster := range clusters { + pbClusters = append(pbClusters, toPBCluster(cluster)) + } + return &pb.FindAllHTTPDNSClustersResponse{Clusters: pbClusters}, nil +} + +func (this *HTTPDNSClusterService) UpdateHTTPDNSClusterDefault(ctx context.Context, req *pb.UpdateHTTPDNSClusterDefaultRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + err = models.SharedHTTPDNSClusterDAO.UpdateDefaultCluster(tx, req.ClusterId) + if err != nil { + return err + } + + clusters, err := models.SharedHTTPDNSClusterDAO.FindAllEnabledClusters(tx) + if err != nil { + return err + } + + for _, cluster := range clusters { + err = notifyHTTPDNSClusterTask(tx, int64(cluster.Id), models.HTTPDNSNodeTaskTypeConfigChanged) + if err != nil { + return err + } + } + return nil + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSClusterService) ListHTTPDNSNodesWithClusterId(ctx context.Context, req *pb.ListHTTPDNSNodesWithClusterIdRequest) (*pb.ListHTTPDNSNodesWithClusterIdResponse, error) { + _, _, err := this.ValidateAdminAndUser(ctx, true) + if err != nil { + return nil, err + } + nodes, err := models.SharedHTTPDNSNodeDAO.ListEnabledNodes(this.NullTx(), req.ClusterId) + if err != nil { + return nil, err + } + var pbNodes []*pb.HTTPDNSNode + for _, node := range nodes { + pbNodes = append(pbNodes, toPBNode(node)) + } + return &pb.ListHTTPDNSNodesWithClusterIdResponse{Nodes: pbNodes}, nil +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_domain.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_domain.go new file mode 100644 index 0000000..1a43d0d --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_domain.go @@ -0,0 +1,112 @@ +package httpdns + +import ( + "context" + "errors" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/dbs" +) + +// HTTPDNSDomainService HTTPDNS域名服务 +type HTTPDNSDomainService struct { + services.BaseService + pb.UnimplementedHTTPDNSDomainServiceServer +} + +func (this *HTTPDNSDomainService) CreateHTTPDNSDomain(ctx context.Context, req *pb.CreateHTTPDNSDomainRequest) (*pb.CreateHTTPDNSDomainResponse, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + if req.AppDbId <= 0 || len(req.Domain) == 0 { + return nil, errors.New("required 'appDbId' and 'domain'") + } + var domainId int64 + err = this.RunTx(func(tx *dbs.Tx) error { + domainId, err = models.SharedHTTPDNSDomainDAO.CreateDomain(tx, req.AppDbId, req.Domain, req.IsOn) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, req.AppDbId, models.HTTPDNSNodeTaskTypeDomainChanged) + }) + if err != nil { + return nil, err + } + return &pb.CreateHTTPDNSDomainResponse{DomainId: domainId}, nil +} + +func (this *HTTPDNSDomainService) DeleteHTTPDNSDomain(ctx context.Context, req *pb.DeleteHTTPDNSDomainRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + domain, err := models.SharedHTTPDNSDomainDAO.FindEnabledDomain(tx, req.DomainId) + if err != nil { + return err + } + if domain == nil { + return nil + } + + err = models.SharedHTTPDNSDomainDAO.DisableDomain(tx, req.DomainId) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, int64(domain.AppId), models.HTTPDNSNodeTaskTypeDomainChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSDomainService) UpdateHTTPDNSDomainStatus(ctx context.Context, req *pb.UpdateHTTPDNSDomainStatusRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + domain, err := models.SharedHTTPDNSDomainDAO.FindEnabledDomain(tx, req.DomainId) + if err != nil { + return err + } + if domain == nil { + return nil + } + + err = models.SharedHTTPDNSDomainDAO.UpdateDomainStatus(tx, req.DomainId, req.IsOn) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, int64(domain.AppId), models.HTTPDNSNodeTaskTypeDomainChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSDomainService) ListHTTPDNSDomainsWithAppId(ctx context.Context, req *pb.ListHTTPDNSDomainsWithAppIdRequest) (*pb.ListHTTPDNSDomainsWithAppIdResponse, error) { + _, _, validateErr := this.ValidateAdminAndUser(ctx, true) + if validateErr != nil { + if _, nodeErr := this.ValidateHTTPDNSNode(ctx); nodeErr != nil { + return nil, validateErr + } + } + domains, err := models.SharedHTTPDNSDomainDAO.ListEnabledDomainsWithAppId(this.NullTx(), req.AppDbId, req.Keyword) + if err != nil { + return nil, err + } + var pbDomains []*pb.HTTPDNSDomain + for _, domain := range domains { + ruleCount, err := models.SharedHTTPDNSCustomRuleDAO.CountEnabledRulesWithDomainId(this.NullTx(), int64(domain.Id)) + if err != nil { + return nil, err + } + pbDomains = append(pbDomains, toPBDomain(domain, ruleCount)) + } + return &pb.ListHTTPDNSDomainsWithAppIdResponse{Domains: pbDomains}, nil +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_node.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_node.go new file mode 100644 index 0000000..463159b --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_node.go @@ -0,0 +1,185 @@ +package httpdns + +import ( + "context" + "encoding/json" + "errors" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/goman" + "github.com/TeaOSLab/EdgeAPI/internal/installers" + "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/logs" +) + +// HTTPDNSNodeService HTTPDNS节点服务 +type HTTPDNSNodeService struct { + services.BaseService + pb.UnimplementedHTTPDNSNodeServiceServer +} + +func (this *HTTPDNSNodeService) CreateHTTPDNSNode(ctx context.Context, req *pb.CreateHTTPDNSNodeRequest) (*pb.CreateHTTPDNSNodeResponse, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + if req.ClusterId <= 0 { + return nil, errors.New("required 'clusterId'") + } + var nodeId int64 + err = this.RunTx(func(tx *dbs.Tx) error { + nodeId, err = models.SharedHTTPDNSNodeDAO.CreateNode(tx, req.ClusterId, req.Name, req.InstallDir, req.IsOn) + if err != nil { + return err + } + return notifyHTTPDNSClusterTask(tx, req.ClusterId, models.HTTPDNSNodeTaskTypeConfigChanged) + }) + if err != nil { + return nil, err + } + return &pb.CreateHTTPDNSNodeResponse{NodeId: nodeId}, nil +} + +func (this *HTTPDNSNodeService) UpdateHTTPDNSNode(ctx context.Context, req *pb.UpdateHTTPDNSNodeRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + node, err := models.SharedHTTPDNSNodeDAO.FindEnabledNode(tx, req.NodeId) + if err != nil { + return err + } + if node == nil { + return errors.New("node not found") + } + + err = models.SharedHTTPDNSNodeDAO.UpdateNode(tx, req.NodeId, req.Name, req.InstallDir, req.IsOn) + if err != nil { + return err + } + return notifyHTTPDNSClusterTask(tx, int64(node.ClusterId), models.HTTPDNSNodeTaskTypeConfigChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSNodeService) DeleteHTTPDNSNode(ctx context.Context, req *pb.DeleteHTTPDNSNodeRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + node, err := models.SharedHTTPDNSNodeDAO.FindEnabledNode(tx, req.NodeId) + if err != nil { + return err + } + if node == nil { + return nil + } + + err = models.SharedHTTPDNSNodeDAO.DisableNode(tx, req.NodeId) + if err != nil { + return err + } + return notifyHTTPDNSClusterTask(tx, int64(node.ClusterId), models.HTTPDNSNodeTaskTypeConfigChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSNodeService) FindHTTPDNSNode(ctx context.Context, req *pb.FindHTTPDNSNodeRequest) (*pb.FindHTTPDNSNodeResponse, error) { + nodeId := req.NodeId + if nodeId <= 0 { + parsedNodeId, nodeErr := this.ValidateHTTPDNSNode(ctx) + if nodeErr != nil { + return nil, errors.New("invalid 'nodeId'") + } + nodeId = parsedNodeId + } else { + _, _, validateErr := this.ValidateAdminAndUser(ctx, true) + if validateErr != nil { + if _, nodeErr := this.ValidateHTTPDNSNode(ctx); nodeErr != nil { + return nil, validateErr + } + } + } + + node, err := models.SharedHTTPDNSNodeDAO.FindEnabledNode(this.NullTx(), nodeId) + if err != nil { + return nil, err + } + return &pb.FindHTTPDNSNodeResponse{Node: toPBNode(node)}, nil +} + +func (this *HTTPDNSNodeService) ListHTTPDNSNodes(ctx context.Context, req *pb.ListHTTPDNSNodesRequest) (*pb.ListHTTPDNSNodesResponse, error) { + _, _, err := this.ValidateAdminAndUser(ctx, true) + if err != nil { + return nil, err + } + nodes, err := models.SharedHTTPDNSNodeDAO.ListEnabledNodes(this.NullTx(), req.ClusterId) + if err != nil { + return nil, err + } + var pbNodes []*pb.HTTPDNSNode + for _, node := range nodes { + pbNodes = append(pbNodes, toPBNode(node)) + } + return &pb.ListHTTPDNSNodesResponse{Nodes: pbNodes}, nil +} + +func (this *HTTPDNSNodeService) UpdateHTTPDNSNodeStatus(ctx context.Context, req *pb.UpdateHTTPDNSNodeStatusRequest) (*pb.RPCSuccess, error) { + nodeId := req.GetNodeId() + isAdminCaller := false + if nodeId > 0 { + if _, adminErr := this.ValidateAdmin(ctx); adminErr == nil { + isAdminCaller = true + } + } + if !isAdminCaller { + if nodeId <= 0 { + parsedNodeId, err := this.ValidateHTTPDNSNode(ctx) + if err != nil { + return nil, err + } + nodeId = parsedNodeId + } + } + if nodeId <= 0 { + return nil, errors.New("invalid 'nodeId'") + } + + err := models.SharedHTTPDNSNodeDAO.UpdateNodeStatus(this.NullTx(), nodeId, req.GetIsUp(), req.GetIsInstalled(), req.GetIsActive(), req.GetStatusJSON(), req.GetInstallStatusJSON()) + if err != nil { + return nil, err + } + + if isAdminCaller && shouldTriggerHTTPDNSInstall(req.GetInstallStatusJSON()) { + goman.New(func() { + installErr := installers.SharedHTTPDNSNodeQueue().InstallNodeProcess(nodeId, false) + if installErr != nil { + logs.Println("[RPC][HTTPDNS]install node failed:", installErr.Error()) + } + }) + } + + return this.Success() +} + +func shouldTriggerHTTPDNSInstall(installStatusJSON []byte) bool { + if len(installStatusJSON) == 0 { + return false + } + + installStatus := &models.NodeInstallStatus{} + err := json.Unmarshal(installStatusJSON, installStatus) + if err != nil { + return false + } + return installStatus.IsRunning && !installStatus.IsFinished +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_rule.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_rule.go new file mode 100644 index 0000000..a8bbd0c --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_rule.go @@ -0,0 +1,193 @@ +package httpdns + +import ( + "context" + "errors" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/dbs" +) + +// HTTPDNSRuleService HTTPDNS规则服务 +type HTTPDNSRuleService struct { + services.BaseService + pb.UnimplementedHTTPDNSRuleServiceServer +} + +func (this *HTTPDNSRuleService) CreateHTTPDNSCustomRule(ctx context.Context, req *pb.CreateHTTPDNSCustomRuleRequest) (*pb.CreateHTTPDNSCustomRuleResponse, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + if req.Rule == nil { + return nil, errors.New("required 'rule'") + } + var ruleId int64 + err = this.RunTx(func(tx *dbs.Tx) error { + rule := &models.HTTPDNSCustomRule{ + AppId: uint32(req.Rule.AppId), + DomainId: uint32(req.Rule.DomainId), + RuleName: req.Rule.RuleName, + LineScope: req.Rule.LineScope, + LineCarrier: req.Rule.LineCarrier, + LineRegion: req.Rule.LineRegion, + LineProvince: req.Rule.LineProvince, + LineContinent: req.Rule.LineContinent, + LineCountry: req.Rule.LineCountry, + TTL: req.Rule.Ttl, + IsOn: req.Rule.IsOn, + Priority: req.Rule.Priority, + } + ruleId, err = models.SharedHTTPDNSCustomRuleDAO.CreateRule(tx, rule) + if err != nil { + return err + } + for _, record := range req.Rule.Records { + _, err := models.SharedHTTPDNSCustomRuleRecordDAO.CreateRecord(tx, ruleId, record.RecordType, record.RecordValue, record.Weight, record.Sort) + if err != nil { + return err + } + } + return notifyHTTPDNSAppTasksByAppDbId(tx, req.Rule.AppId, models.HTTPDNSNodeTaskTypeRuleChanged) + }) + if err != nil { + return nil, err + } + return &pb.CreateHTTPDNSCustomRuleResponse{RuleId: ruleId}, nil +} + +func (this *HTTPDNSRuleService) UpdateHTTPDNSCustomRule(ctx context.Context, req *pb.UpdateHTTPDNSCustomRuleRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + if req.Rule == nil || req.Rule.Id <= 0 { + return nil, errors.New("invalid 'rule.id'") + } + err = this.RunTx(func(tx *dbs.Tx) error { + oldRule, err := models.SharedHTTPDNSCustomRuleDAO.FindEnabledRule(tx, req.Rule.Id) + if err != nil { + return err + } + if oldRule == nil { + return errors.New("rule not found") + } + + rule := &models.HTTPDNSCustomRule{ + Id: uint32(req.Rule.Id), + RuleName: req.Rule.RuleName, + LineScope: req.Rule.LineScope, + LineCarrier: req.Rule.LineCarrier, + LineRegion: req.Rule.LineRegion, + LineProvince: req.Rule.LineProvince, + LineContinent: req.Rule.LineContinent, + LineCountry: req.Rule.LineCountry, + TTL: req.Rule.Ttl, + IsOn: req.Rule.IsOn, + Priority: req.Rule.Priority, + } + err = models.SharedHTTPDNSCustomRuleDAO.UpdateRule(tx, rule) + if err != nil { + return err + } + err = models.SharedHTTPDNSCustomRuleRecordDAO.DisableRecordsWithRuleId(tx, req.Rule.Id) + if err != nil { + return err + } + for _, record := range req.Rule.Records { + _, err := models.SharedHTTPDNSCustomRuleRecordDAO.CreateRecord(tx, req.Rule.Id, record.RecordType, record.RecordValue, record.Weight, record.Sort) + if err != nil { + return err + } + } + err = notifyHTTPDNSAppTasksByAppDbId(tx, int64(oldRule.AppId), models.HTTPDNSNodeTaskTypeRuleChanged) + if err != nil { + return err + } + + targetAppDbId := req.Rule.AppId + if targetAppDbId <= 0 { + targetAppDbId = int64(oldRule.AppId) + } + return notifyHTTPDNSAppTasksByAppDbId(tx, targetAppDbId, models.HTTPDNSNodeTaskTypeRuleChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSRuleService) DeleteHTTPDNSCustomRule(ctx context.Context, req *pb.DeleteHTTPDNSCustomRuleRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + rule, err := models.SharedHTTPDNSCustomRuleDAO.FindEnabledRule(tx, req.RuleId) + if err != nil { + return err + } + if rule == nil { + return nil + } + + err = models.SharedHTTPDNSCustomRuleDAO.DisableRule(tx, req.RuleId) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, int64(rule.AppId), models.HTTPDNSNodeTaskTypeRuleChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSRuleService) UpdateHTTPDNSCustomRuleStatus(ctx context.Context, req *pb.UpdateHTTPDNSCustomRuleStatusRequest) (*pb.RPCSuccess, error) { + _, err := this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + err = this.RunTx(func(tx *dbs.Tx) error { + rule, err := models.SharedHTTPDNSCustomRuleDAO.FindEnabledRule(tx, req.RuleId) + if err != nil { + return err + } + if rule == nil { + return nil + } + + err = models.SharedHTTPDNSCustomRuleDAO.UpdateRuleStatus(tx, req.RuleId, req.IsOn) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByAppDbId(tx, int64(rule.AppId), models.HTTPDNSNodeTaskTypeRuleChanged) + }) + if err != nil { + return nil, err + } + return this.Success() +} + +func (this *HTTPDNSRuleService) ListHTTPDNSCustomRulesWithDomainId(ctx context.Context, req *pb.ListHTTPDNSCustomRulesWithDomainIdRequest) (*pb.ListHTTPDNSCustomRulesWithDomainIdResponse, error) { + _, _, validateErr := this.ValidateAdminAndUser(ctx, true) + if validateErr != nil { + if _, nodeErr := this.ValidateHTTPDNSNode(ctx); nodeErr != nil { + return nil, validateErr + } + } + rules, err := models.SharedHTTPDNSCustomRuleDAO.ListEnabledRulesWithDomainId(this.NullTx(), req.DomainId) + if err != nil { + return nil, err + } + var pbRules []*pb.HTTPDNSCustomRule + for _, rule := range rules { + records, err := models.SharedHTTPDNSCustomRuleRecordDAO.ListEnabledRecordsWithRuleId(this.NullTx(), int64(rule.Id)) + if err != nil { + return nil, err + } + pbRules = append(pbRules, toPBRule(rule, records)) + } + return &pb.ListHTTPDNSCustomRulesWithDomainIdResponse{Rules: pbRules}, nil +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_runtime_log.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_runtime_log.go new file mode 100644 index 0000000..a56ef93 --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_runtime_log.go @@ -0,0 +1,107 @@ +package httpdns + +import ( + "context" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + timeutil "github.com/iwind/TeaGo/utils/time" + "time" +) + +// HTTPDNSRuntimeLogService HTTPDNS运行日志服务 +type HTTPDNSRuntimeLogService struct { + services.BaseService + pb.UnimplementedHTTPDNSRuntimeLogServiceServer +} + +func (this *HTTPDNSRuntimeLogService) CreateHTTPDNSRuntimeLogs(ctx context.Context, req *pb.CreateHTTPDNSRuntimeLogsRequest) (*pb.CreateHTTPDNSRuntimeLogsResponse, error) { + nodeIdInContext, err := this.ValidateHTTPDNSNode(ctx) + if err != nil { + _, err = this.ValidateAdmin(ctx) + if err != nil { + return nil, err + } + } + for _, item := range req.Logs { + createdAt := item.CreatedAt + if createdAt <= 0 { + createdAt = time.Now().Unix() + } + day := item.Day + if len(day) == 0 { + day = timeutil.Format("Ymd") + } + nodeId := item.NodeId + // When called by HTTPDNS node, trust node id parsed from RPC token. + if nodeIdInContext > 0 { + nodeId = nodeIdInContext + } + + clusterId := item.ClusterId + if clusterId <= 0 && nodeId > 0 { + clusterId, _ = models.SharedHTTPDNSNodeDAO.FindNodeClusterId(this.NullTx(), nodeId) + } + + log := &models.HTTPDNSRuntimeLog{ + ClusterId: uint32(clusterId), + NodeId: uint32(nodeId), + Level: item.Level, + Type: item.Type, + Module: item.Module, + Description: item.Description, + Count: item.Count, + RequestId: item.RequestId, + CreatedAt: uint64(createdAt), + Day: day, + } + err := models.SharedHTTPDNSRuntimeLogDAO.CreateLog(this.NullTx(), log) + if err != nil { + return nil, err + } + } + return &pb.CreateHTTPDNSRuntimeLogsResponse{}, nil +} + +func (this *HTTPDNSRuntimeLogService) ListHTTPDNSRuntimeLogs(ctx context.Context, req *pb.ListHTTPDNSRuntimeLogsRequest) (*pb.ListHTTPDNSRuntimeLogsResponse, error) { + _, _, err := this.ValidateAdminAndUser(ctx, true) + if err != nil { + return nil, err + } + total, err := models.SharedHTTPDNSRuntimeLogDAO.CountLogs(this.NullTx(), req.Day, req.ClusterId, req.NodeId, req.Level, req.Keyword) + if err != nil { + return nil, err + } + logs, err := models.SharedHTTPDNSRuntimeLogDAO.ListLogs(this.NullTx(), req.Day, req.ClusterId, req.NodeId, req.Level, req.Keyword, req.Offset, req.Size) + if err != nil { + return nil, err + } + var pbLogs []*pb.HTTPDNSRuntimeLog + for _, item := range logs { + clusterName, _ := models.SharedHTTPDNSClusterDAO.FindEnabledClusterName(this.NullTx(), int64(item.ClusterId)) + nodeName := "" + node, _ := models.SharedHTTPDNSNodeDAO.FindEnabledNode(this.NullTx(), int64(item.NodeId)) + if node != nil { + nodeName = node.Name + } + pbLogs = append(pbLogs, &pb.HTTPDNSRuntimeLog{ + Id: int64(item.Id), + ClusterId: int64(item.ClusterId), + NodeId: int64(item.NodeId), + Level: item.Level, + Type: item.Type, + Module: item.Module, + Description: item.Description, + Count: item.Count, + RequestId: item.RequestId, + CreatedAt: int64(item.CreatedAt), + Day: item.Day, + ClusterName: clusterName, + NodeName: nodeName, + }) + } + return &pb.ListHTTPDNSRuntimeLogsResponse{ + Logs: pbLogs, + Total: total, + }, nil +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_sandbox.go b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_sandbox.go new file mode 100644 index 0000000..b853f24 --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/service_httpdns_sandbox.go @@ -0,0 +1,252 @@ +package httpdns + +import ( + "context" + "crypto/hmac" + "crypto/sha256" + "crypto/tls" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/rpc/services" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/rands" + "io" + "net/http" + "net/url" + "strconv" + "strings" + "time" +) + +// HTTPDNSSandboxService HTTPDNS解析测试服务 +type HTTPDNSSandboxService struct { + services.BaseService + pb.UnimplementedHTTPDNSSandboxServiceServer +} + +// nodeResolveResponse 节点返回的 JSON 结构(对齐 EdgeHttpDNS resolve_server.go) +type nodeResolveResponse struct { + Code string `json:"code"` + Message string `json:"message"` + RequestID string `json:"requestId"` + Data *nodeResolveData `json:"data,omitempty"` +} + +type nodeResolveData struct { + Domain string `json:"domain"` + QType string `json:"qtype"` + TTL int32 `json:"ttl"` + Records []*nodeResolveRecord `json:"records"` + Client *nodeClientInfo `json:"client"` + Summary string `json:"summary"` +} + +type nodeResolveRecord struct { + Type string `json:"type"` + IP string `json:"ip"` + Weight int32 `json:"weight"` + Line string `json:"line"` + Region string `json:"region"` +} + +type nodeClientInfo struct { + IP string `json:"ip"` + Region string `json:"region"` + Carrier string `json:"carrier"` + Country string `json:"country"` +} + +func (this *HTTPDNSSandboxService) TestHTTPDNSResolve(ctx context.Context, req *pb.TestHTTPDNSResolveRequest) (*pb.TestHTTPDNSResolveResponse, error) { + _, _, err := this.ValidateAdminAndUser(ctx, true) + if err != nil { + return nil, err + } + + if len(req.AppId) == 0 || len(req.Domain) == 0 { + return nil, errors.New("appId 和 domain 不能为空") + } + + app, err := models.SharedHTTPDNSAppDAO.FindEnabledAppWithAppId(this.NullTx(), req.AppId) + if err != nil { + return nil, err + } + if app == nil || !app.IsOn { + return &pb.TestHTTPDNSResolveResponse{ + Code: "APP_NOT_FOUND_OR_DISABLED", + Message: "找不到指定的应用,或该应用已下线", + RequestId: "rid-" + rands.HexString(12), + }, nil + } + if req.ClusterId > 0 && req.ClusterId != int64(app.PrimaryClusterId) && req.ClusterId != int64(app.BackupClusterId) { + return &pb.TestHTTPDNSResolveResponse{ + Code: "APP_CLUSTER_MISMATCH", + Message: "当前应用未绑定到该集群 (主集群: " + strconv.FormatInt(int64(app.PrimaryClusterId), 10) + ", 备用集群: " + strconv.FormatInt(int64(app.BackupClusterId), 10) + ")", + RequestId: "rid-" + rands.HexString(12), + }, nil + } + + qtype := strings.ToUpper(strings.TrimSpace(req.Qtype)) + if qtype == "" { + qtype = "A" + } + + // 获取集群服务域名 + clusterId := req.ClusterId + if clusterId <= 0 { + clusterId = int64(app.PrimaryClusterId) + } + cluster, err := models.SharedHTTPDNSClusterDAO.FindEnabledCluster(this.NullTx(), clusterId) + if err != nil { + return nil, err + } + if cluster == nil { + return &pb.TestHTTPDNSResolveResponse{ + Code: "CLUSTER_NOT_FOUND", + Message: "找不到指定的集群", + RequestId: "rid-" + rands.HexString(12), + }, nil + } + + serviceDomain := strings.TrimSpace(cluster.ServiceDomain) + if len(serviceDomain) == 0 { + return &pb.TestHTTPDNSResolveResponse{ + Code: "NO_SERVICE_DOMAIN", + Message: "该集群未配置服务域名", + RequestId: "rid-" + rands.HexString(12), + }, nil + } + + // 构造请求转发到 EdgeHttpDNS 节点 + secret, err := models.SharedHTTPDNSAppSecretDAO.FindEnabledAppSecret(this.NullTx(), int64(app.Id)) + if err != nil { + return nil, err + } + + query := url.Values{} + query.Set("appId", req.AppId) + query.Set("dn", req.Domain) + query.Set("qtype", qtype) + if len(req.ClientIP) > 0 { + query.Set("cip", req.ClientIP) + } + if len(req.Sid) > 0 { + query.Set("sid", req.Sid) + } + if len(req.SdkVersion) > 0 { + query.Set("sdk_version", req.SdkVersion) + } + if len(req.Os) > 0 { + query.Set("os", req.Os) + } + + // 应用开启验签时,沙盒自动生成签名参数,避免测试请求被拒绝 + if secret != nil && secret.SignEnabled { + signSecret := strings.TrimSpace(secret.SignSecret) + if len(signSecret) == 0 { + return &pb.TestHTTPDNSResolveResponse{ + Code: "SIGN_INVALID", + Message: "应用开启了请求验签,但未配置有效加签 Secret", + RequestId: "rid-" + rands.HexString(12), + Domain: req.Domain, + Qtype: qtype, + }, nil + } + + exp := strconv.FormatInt(time.Now().Unix()+300, 10) + nonce := "sandbox-" + rands.HexString(16) + sign := buildSandboxResolveSign(signSecret, req.AppId, req.Domain, qtype, exp, nonce) + + query.Set("exp", exp) + query.Set("nonce", nonce) + query.Set("sign", sign) + } + + resolveURL := "https://" + serviceDomain + "/resolve?" + query.Encode() + + httpClient := &http.Client{ + Timeout: 5 * time.Second, + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, // 沙盒测试环境允许自签名证书 + }, + }, + } + + httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, resolveURL, nil) + if err != nil { + return nil, fmt.Errorf("构建请求失败: %w", err) + } + + resp, err := httpClient.Do(httpReq) + if err != nil { + return &pb.TestHTTPDNSResolveResponse{ + Code: "NODE_UNREACHABLE", + Message: "无法连接到 HTTPDNS 节点: " + err.Error(), + RequestId: "rid-" + rands.HexString(12), + Domain: req.Domain, + Qtype: qtype, + }, nil + } + defer resp.Body.Close() + + body, err := io.ReadAll(io.LimitReader(resp.Body, 64*1024)) + if err != nil { + return nil, fmt.Errorf("读取节点响应失败: %w", err) + } + + // 解析节点返回的 JSON + var nodeResp nodeResolveResponse + if err := json.Unmarshal(body, &nodeResp); err != nil { + return &pb.TestHTTPDNSResolveResponse{ + Code: "PARSE_ERROR", + Message: "解析节点返回数据失败: " + err.Error(), + RequestId: "rid-" + rands.HexString(12), + Domain: req.Domain, + Qtype: qtype, + }, nil + } + + // 映射节点响应到 protobuf 响应 + pbResp := &pb.TestHTTPDNSResolveResponse{ + Code: nodeResp.Code, + Message: nodeResp.Message, + RequestId: nodeResp.RequestID, + Domain: req.Domain, + Qtype: qtype, + } + + if nodeResp.Data != nil { + pbResp.Ttl = nodeResp.Data.TTL + pbResp.Summary = nodeResp.Data.Summary + + if nodeResp.Data.Client != nil { + pbResp.ClientIP = nodeResp.Data.Client.IP + pbResp.ClientRegion = nodeResp.Data.Client.Region + pbResp.ClientCarrier = nodeResp.Data.Client.Carrier + pbResp.ClientCountry = nodeResp.Data.Client.Country + } + + for _, rec := range nodeResp.Data.Records { + pbResp.Records = append(pbResp.Records, &pb.HTTPDNSResolveRecord{ + Type: rec.Type, + Ip: rec.IP, + Ttl: nodeResp.Data.TTL, + Weight: rec.Weight, + Line: rec.Line, + Region: rec.Region, + }) + } + } + + return pbResp, nil +} + +func buildSandboxResolveSign(signSecret string, appID string, domain string, qtype string, exp string, nonce string) string { + raw := strings.TrimSpace(appID) + "|" + strings.ToLower(strings.TrimSpace(domain)) + "|" + strings.ToUpper(strings.TrimSpace(qtype)) + "|" + strings.TrimSpace(exp) + "|" + strings.TrimSpace(nonce) + mac := hmac.New(sha256.New, []byte(strings.TrimSpace(signSecret))) + _, _ = mac.Write([]byte(raw)) + return hex.EncodeToString(mac.Sum(nil)) +} diff --git a/EdgeAPI/internal/rpc/services/httpdns/task_notify.go b/EdgeAPI/internal/rpc/services/httpdns/task_notify.go new file mode 100644 index 0000000..a6a1088 --- /dev/null +++ b/EdgeAPI/internal/rpc/services/httpdns/task_notify.go @@ -0,0 +1,49 @@ +package httpdns + +import ( + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" + "github.com/iwind/TeaGo/dbs" +) + +func notifyHTTPDNSClusterTask(tx *dbs.Tx, clusterId int64, taskType models.NodeTaskType) error { + if clusterId <= 0 { + return nil + } + return models.SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleHTTPDNS, clusterId, 0, 0, taskType) +} + +func notifyHTTPDNSAppTasksByApp(tx *dbs.Tx, app *models.HTTPDNSApp, taskType models.NodeTaskType) error { + if app == nil { + return nil + } + + primaryClusterId := int64(app.PrimaryClusterId) + backupClusterId := int64(app.BackupClusterId) + + err := notifyHTTPDNSClusterTask(tx, primaryClusterId, taskType) + if err != nil { + return err + } + + if backupClusterId > 0 && backupClusterId != primaryClusterId { + err = notifyHTTPDNSClusterTask(tx, backupClusterId, taskType) + if err != nil { + return err + } + } + + return nil +} + +func notifyHTTPDNSAppTasksByAppDbId(tx *dbs.Tx, appDbId int64, taskType models.NodeTaskType) error { + if appDbId <= 0 { + return nil + } + + app, err := models.SharedHTTPDNSAppDAO.FindEnabledApp(tx, appDbId) + if err != nil { + return err + } + return notifyHTTPDNSAppTasksByApp(tx, app, taskType) +} diff --git a/EdgeAPI/internal/rpc/services/service_base.go b/EdgeAPI/internal/rpc/services/service_base.go index 66fb9fe..661ba99 100644 --- a/EdgeAPI/internal/rpc/services/service_base.go +++ b/EdgeAPI/internal/rpc/services/service_base.go @@ -83,6 +83,12 @@ func (this *BaseService) ValidateNSNode(ctx context.Context) (nodeId int64, err return } +// ValidateHTTPDNSNode 校验HTTPDNS节点 +func (this *BaseService) ValidateHTTPDNSNode(ctx context.Context) (nodeId int64, err error) { + _, _, nodeId, err = rpcutils.ValidateRequest(ctx, rpcutils.UserTypeHTTPDNS) + return +} + // ValidateUserNode 校验用户节点 func (this *BaseService) ValidateUserNode(ctx context.Context, canRest bool) (userId int64, err error) { // 不允许REST调用 @@ -105,7 +111,7 @@ func (this *BaseService) ValidateAuthorityNode(ctx context.Context) (nodeId int6 func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.UserType) (role rpcutils.UserType, nodeIntId int64, err error) { // 默认包含大部分节点 if len(roles) == 0 { - roles = []rpcutils.UserType{rpcutils.UserTypeNode, rpcutils.UserTypeCluster, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeDNS, rpcutils.UserTypeReport, rpcutils.UserTypeLog, rpcutils.UserTypeAPI} + roles = []rpcutils.UserType{rpcutils.UserTypeNode, rpcutils.UserTypeCluster, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeDNS, rpcutils.UserTypeHTTPDNS, rpcutils.UserTypeReport, rpcutils.UserTypeLog, rpcutils.UserTypeAPI} } if ctx == nil { @@ -191,6 +197,8 @@ func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.U nodeIntId = 0 case rpcutils.UserTypeDNS: nodeIntId, err = models.SharedNSNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId) + case rpcutils.UserTypeHTTPDNS: + nodeIntId, err = models.SharedHTTPDNSNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId) case rpcutils.UserTypeReport: nodeIntId, err = models.SharedReportNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId) case rpcutils.UserTypeAuthority: diff --git a/EdgeAPI/internal/rpc/services/service_node_task.go b/EdgeAPI/internal/rpc/services/service_node_task.go index 5651fb7..b7fa3a7 100644 --- a/EdgeAPI/internal/rpc/services/service_node_task.go +++ b/EdgeAPI/internal/rpc/services/service_node_task.go @@ -19,7 +19,7 @@ type NodeTaskService struct { // FindNodeTasks 获取单节点同步任务 func (this *NodeTaskService) FindNodeTasks(ctx context.Context, req *pb.FindNodeTasksRequest) (*pb.FindNodeTasksResponse, error) { - nodeType, nodeId, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS) + nodeType, nodeId, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS, rpcutils.UserTypeHTTPDNS) if err != nil { return nil, err } @@ -65,7 +65,7 @@ func (this *NodeTaskService) FindNodeTasks(ctx context.Context, req *pb.FindNode // ReportNodeTaskDone 报告同步任务结果 func (this *NodeTaskService) ReportNodeTaskDone(ctx context.Context, req *pb.ReportNodeTaskDoneRequest) (*pb.RPCSuccess, error) { - _, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS) + _, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS, rpcutils.UserTypeHTTPDNS) if err != nil { return nil, err } diff --git a/EdgeAPI/internal/rpc/utils/utils.go b/EdgeAPI/internal/rpc/utils/utils.go index 6ea6906..cb9f459 100644 --- a/EdgeAPI/internal/rpc/utils/utils.go +++ b/EdgeAPI/internal/rpc/utils/utils.go @@ -16,6 +16,7 @@ const ( UserTypeCluster = "cluster" UserTypeStat = "stat" UserTypeDNS = "dns" + UserTypeHTTPDNS = "httpdns" UserTypeLog = "log" UserTypeAPI = "api" UserTypeAuthority = "authority" diff --git a/EdgeAPI/internal/rpc/utils/utils_ext.go b/EdgeAPI/internal/rpc/utils/utils_ext.go index aa8c0aa..a1ae946 100644 --- a/EdgeAPI/internal/rpc/utils/utils_ext.go +++ b/EdgeAPI/internal/rpc/utils/utils_ext.go @@ -142,6 +142,16 @@ func ValidateRequest(ctx context.Context, userTypes ...UserType) (userType UserT return UserTypeUser, 0, 0, errors.New("context: not found node with id '" + nodeId + "'") } resultNodeId = nodeIntId + case UserTypeHTTPDNS: + nodeIntId, err := models.SharedHTTPDNSNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId) + if err != nil { + return UserTypeHTTPDNS, nodeIntId, 0, errors.New("context: " + err.Error()) + } + if nodeIntId <= 0 { + return UserTypeHTTPDNS, nodeIntId, 0, errors.New("context: not found node with id '" + nodeId + "'") + } + nodeUserId = nodeIntId + resultNodeId = nodeIntId } if nodeUserId > 0 { diff --git a/EdgeAPI/internal/rpc/utils/utils_ext_plus.go b/EdgeAPI/internal/rpc/utils/utils_ext_plus.go index 49d8784..8a9e133 100644 --- a/EdgeAPI/internal/rpc/utils/utils_ext_plus.go +++ b/EdgeAPI/internal/rpc/utils/utils_ext_plus.go @@ -171,6 +171,16 @@ func ValidateRequest(ctx context.Context, userTypes ...UserType) (userType UserT } nodeUserId = nodeIntId resultNodeId = nodeIntId + case UserTypeHTTPDNS: + nodeIntId, err := models.SharedHTTPDNSNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId) + if err != nil { + return UserTypeHTTPDNS, nodeIntId, 0, errors.New("context: " + err.Error()) + } + if nodeIntId <= 0 { + return UserTypeHTTPDNS, nodeIntId, 0, errors.New("context: not found node with id '" + nodeId + "'") + } + nodeUserId = nodeIntId + resultNodeId = nodeIntId case UserTypeReport: nodeIntId, err := models.SharedReportNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId) if err != nil { diff --git a/EdgeAPI/internal/setup/clickhouse_upgrade.go b/EdgeAPI/internal/setup/clickhouse_upgrade.go new file mode 100644 index 0000000..865c5fa --- /dev/null +++ b/EdgeAPI/internal/setup/clickhouse_upgrade.go @@ -0,0 +1,132 @@ +package setup + +import ( + "context" + "strings" + "time" + + "github.com/TeaOSLab/EdgeAPI/internal/clickhouse" +) + +// EnsureClickHouseTables 自动确保日志相关 ClickHouse 表存在。 +// 仅做 CREATE TABLE IF NOT EXISTS,不会覆盖已有表结构。 +func EnsureClickHouseTables() error { + client := clickhouse.NewClient() + if !client.IsConfigured() { + return nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + sqls := []string{ + `CREATE TABLE IF NOT EXISTS logs_ingest +( + timestamp DateTime CODEC(DoubleDelta, ZSTD(1)), + node_id UInt64, + cluster_id UInt64, + server_id UInt64, + host LowCardinality(String), + ip String, + method LowCardinality(String), + path String CODEC(ZSTD(1)), + status UInt16, + bytes_in UInt64 CODEC(Delta, ZSTD(1)), + bytes_out UInt64 CODEC(Delta, ZSTD(1)), + cost_ms UInt32 CODEC(Delta, ZSTD(1)), + ua String CODEC(ZSTD(1)), + referer String CODEC(ZSTD(1)), + log_type LowCardinality(String), + trace_id String, + firewall_policy_id UInt64 DEFAULT 0, + firewall_rule_group_id UInt64 DEFAULT 0, + firewall_rule_set_id UInt64 DEFAULT 0, + firewall_rule_id UInt64 DEFAULT 0, + request_headers String CODEC(ZSTD(3)) DEFAULT '', + request_body String CODEC(ZSTD(3)) DEFAULT '', + response_headers String CODEC(ZSTD(3)) DEFAULT '', + response_body String CODEC(ZSTD(3)) DEFAULT '', + INDEX idx_trace_id trace_id TYPE bloom_filter(0.01) GRANULARITY 4, + INDEX idx_ip ip TYPE bloom_filter(0.01) GRANULARITY 4, + INDEX idx_host host TYPE tokenbf_v1(10240, 3, 0) GRANULARITY 4, + INDEX idx_fw_policy firewall_policy_id TYPE minmax GRANULARITY 4, + INDEX idx_status status TYPE minmax GRANULARITY 4 +) +ENGINE = MergeTree +PARTITION BY toYYYYMMDD(timestamp) +ORDER BY (timestamp, node_id, server_id, trace_id) +SETTINGS index_granularity = 8192`, + `CREATE TABLE IF NOT EXISTS dns_logs_ingest +( + timestamp DateTime CODEC(DoubleDelta, ZSTD(1)), + request_id String, + node_id UInt64, + cluster_id UInt64, + domain_id UInt64, + record_id UInt64, + remote_addr String, + question_name String, + question_type LowCardinality(String), + record_name String, + record_type LowCardinality(String), + record_value String, + networking LowCardinality(String), + is_recursive UInt8, + error String CODEC(ZSTD(1)), + ns_route_codes Array(String), + content_json String CODEC(ZSTD(3)) DEFAULT '', + INDEX idx_request_id request_id TYPE bloom_filter(0.01) GRANULARITY 4, + INDEX idx_remote_addr remote_addr TYPE bloom_filter(0.01) GRANULARITY 4, + INDEX idx_question_name question_name TYPE tokenbf_v1(10240, 3, 0) GRANULARITY 4, + INDEX idx_domain_id domain_id TYPE minmax GRANULARITY 4 +) +ENGINE = MergeTree +PARTITION BY toYYYYMMDD(timestamp) +ORDER BY (timestamp, request_id, node_id) +SETTINGS index_granularity = 8192`, + `CREATE TABLE IF NOT EXISTS httpdns_access_logs_ingest +( + request_id String, + cluster_id UInt64, + node_id UInt64, + app_id String, + app_name String, + domain String, + qtype LowCardinality(String), + client_ip String, + client_region String, + carrier String, + sdk_version String, + os LowCardinality(String), + result_ips String, + status LowCardinality(String), + error_code String, + cost_ms UInt32, + created_at UInt64, + day String, + summary String CODEC(ZSTD(1)), + INDEX idx_request_id request_id TYPE bloom_filter(0.01) GRANULARITY 4, + INDEX idx_cluster_id cluster_id TYPE minmax GRANULARITY 4, + INDEX idx_node_id node_id TYPE minmax GRANULARITY 4, + INDEX idx_app_id app_id TYPE tokenbf_v1(10240, 3, 0) GRANULARITY 4, + INDEX idx_domain domain TYPE tokenbf_v1(10240, 3, 0) GRANULARITY 4, + INDEX idx_status status TYPE minmax GRANULARITY 4 +) +ENGINE = MergeTree +PARTITION BY day +ORDER BY (day, created_at, request_id, node_id) +SETTINGS index_granularity = 8192`, + } + + for _, sql := range sqls { + stmt := strings.TrimSpace(sql) + if len(stmt) == 0 { + continue + } + if err := client.Execute(ctx, stmt); err != nil { + return err + } + } + + return nil +} diff --git a/EdgeAPI/internal/setup/sql_upgrade.go b/EdgeAPI/internal/setup/sql_upgrade.go index ff0e77b..205f16b 100644 --- a/EdgeAPI/internal/setup/sql_upgrade.go +++ b/EdgeAPI/internal/setup/sql_upgrade.go @@ -110,6 +110,9 @@ var upgradeFuncs = []*upgradeVersion{ { "1.4.4", upgradeV1_4_4, }, + { + "1.4.8", upgradeV1_4_8, + }, } // UpgradeSQLData 升级SQL数据 @@ -269,14 +272,14 @@ func upgradeV0_0_10(db *dbs.DB) error { // v0.2.5 func upgradeV0_2_5(db *dbs.DB) error { - // 更新用户 + // 鏇存柊鐢ㄦ埛 _, err := db.Exec("UPDATE edgeUsers SET day=FROM_UNIXTIME(createdAt,'%Y%m%d') WHERE day IS NULL OR LENGTH(day)=0") if err != nil { return err } - // 更新防火墙规则 - ones, _, err := db.FindOnes("SELECT id, actions, action, actionOptions FROM edgeHTTPFirewallRuleSets WHERE actions IS NULL OR LENGTH(actions)=0") + // 更新防火墙规则 + ones, _, err := db.FindOnes("SELECT id, actions, action, actionOptions FROM edgeHTTPFirewallRuleSets WHERE actions IS NULL OR LENGTH(actions)=0") if err != nil { return err } @@ -309,8 +312,8 @@ func upgradeV0_2_5(db *dbs.DB) error { // v0.3.0 func upgradeV0_3_0(db *dbs.DB) error { - // 升级健康检查 - ones, _, err := db.FindOnes("SELECT id,healthCheck FROM edgeNodeClusters WHERE state=1") + // 升级健康检查 + ones, _, err := db.FindOnes("SELECT id,healthCheck FROM edgeNodeClusters WHERE state=1") if err != nil { return err } @@ -342,11 +345,10 @@ func upgradeV0_3_0(db *dbs.DB) error { // v0.3.1 func upgradeV0_3_1(db *dbs.DB) error { - // 清空域名统计,已使用分表代替 - // 因为可能有权限问题,所以我们忽略错误 - _, _ = db.Exec("TRUNCATE table edgeServerDomainHourlyStats") + // 娓呯┖鍩熷悕缁熻锛屽凡浣跨敤鍒嗚〃浠f浛 + // 鍥犱负鍙兘鏈夋潈闄愰棶棰橈紝鎵€浠ユ垜浠拷鐣ラ敊璇? _, _ = db.Exec("TRUNCATE table edgeServerDomainHourlyStats") - // 升级APIToken + // 鍗囩骇APIToken ones, _, err := db.FindOnes("SELECT uniqueId,secret FROM edgeNodeClusters") if err != nil { return err @@ -374,9 +376,9 @@ func upgradeV0_3_2(db *dbs.DB) error { // gzip => compression type HTTPGzipRef struct { - IsPrior bool `yaml:"isPrior" json:"isPrior"` // 是否覆盖 - IsOn bool `yaml:"isOn" json:"isOn"` // 是否开启 - GzipId int64 `yaml:"gzipId" json:"gzipId"` // 使用的配置ID + IsPrior bool `yaml:"isPrior" json:"isPrior"` // 鏄惁瑕嗙洊 + IsOn bool `yaml:"isOn" json:"isOn"` // 是否开启 + GzipId int64 `yaml:"gzipId" json:"gzipId"` // 使用的配置ID } webOnes, _, err := db.FindOnes("SELECT id, gzip FROM edgeHTTPWebs WHERE gzip IS NOT NULL AND compression IS NULL") @@ -458,7 +460,7 @@ func upgradeV0_3_2(db *dbs.DB) error { } } - // 更新服务端口 + // 鏇存柊鏈嶅姟绔彛 var serverDAO = models.NewServerDAO() ones, err := serverDAO.Query(nil). ResultPk(). @@ -479,14 +481,14 @@ func upgradeV0_3_2(db *dbs.DB) error { // v0.3.3 func upgradeV0_3_3(db *dbs.DB) error { - // 升级CC请求数Code - _, err := db.Exec("UPDATE edgeHTTPFirewallRuleSets SET code='8002' WHERE name='CC请求数' AND code='8001'") + // 鍗囩骇CC璇锋眰鏁癈ode + _, err := db.Exec("UPDATE edgeHTTPFirewallRuleSets SET code='8002' WHERE name='CC璇锋眰鏁? AND code='8001'") if err != nil { return err } - // 清除节点 - // 删除7天以前的info日志 + // 娓呴櫎鑺傜偣 + // 鍒犻櫎7澶╀互鍓嶇殑info鏃ュ織 err = models.NewNodeLogDAO().DeleteExpiredLogsWithLevel(nil, "info", 7) if err != nil { return err @@ -497,13 +499,13 @@ func upgradeV0_3_3(db *dbs.DB) error { // v0.3.7 func upgradeV0_3_7(db *dbs.DB) error { - // 修改所有edgeNodeGrants中的su为0 + // 淇敼鎵€鏈塭dgeNodeGrants涓殑su涓? _, err := db.Exec("UPDATE edgeNodeGrants SET su=0 WHERE su=1") if err != nil { return err } - // WAF预置分组 + // WAF棰勭疆鍒嗙粍 _, err = db.Exec("UPDATE edgeHTTPFirewallRuleGroups SET isTemplate=1 WHERE LENGTH(code)>0") if err != nil { return err @@ -514,7 +516,7 @@ func upgradeV0_3_7(db *dbs.DB) error { // v0.4.0 func upgradeV0_4_0(db *dbs.DB) error { - // 升级SYN Flood配置 + // 鍗囩骇SYN Flood閰嶇疆 synFloodJSON, err := json.Marshal(firewallconfigs.NewSYNFloodConfig()) if err == nil { _, err := db.Exec("UPDATE edgeHTTPFirewallPolicies SET synFlood=? WHERE synFlood IS NULL AND state=1", string(synFloodJSON)) @@ -528,13 +530,13 @@ func upgradeV0_4_0(db *dbs.DB) error { // v0.4.1 func upgradeV0_4_1(db *dbs.DB) error { - // 升级 servers.lastUserPlanId + // 鍗囩骇 servers.lastUserPlanId _, err := db.Exec("UPDATE edgeServers SET lastUserPlanId=userPlanId WHERE userPlanId>0") if err != nil { return err } - // 执行域名统计清理 + // 鎵ц鍩熷悕缁熻娓呯悊 err = stats.NewServerDomainHourlyStatDAO().CleanDays(nil, 7) if err != nil { return err @@ -545,7 +547,7 @@ func upgradeV0_4_1(db *dbs.DB) error { // v0.4.5 func upgradeV0_4_5(db *dbs.DB) error { - // 升级访问日志自动分表 + // 鍗囩骇璁块棶鏃ュ織鑷姩鍒嗚〃 { var dao = models.NewSysSettingDAO() valueJSON, err := dao.ReadSetting(nil, systemconfigs.SettingCodeAccessLogQueue) @@ -569,7 +571,7 @@ func upgradeV0_4_5(db *dbs.DB) error { } } - // 升级一个防SQL注入规则 + // 鍗囩骇涓€涓槻SQL娉ㄥ叆瑙勫垯 { ones, _, err := db.FindOnes(`SELECT id FROM edgeHTTPFirewallRules WHERE value=?`, "(updatexml|extractvalue|ascii|ord|char|chr|count|concat|rand|floor|substr|length|len|user|database|benchmark|analyse)\\s*\\(") if err != nil { @@ -589,7 +591,7 @@ func upgradeV0_4_5(db *dbs.DB) error { // v0.4.7 func upgradeV0_4_7(db *dbs.DB) error { - // 升级 edgeServers 中的 plainServerNames + // 鍗囩骇 edgeServers 涓殑 plainServerNames { ones, _, err := db.FindOnes("SELECT id,serverNames FROM edgeServers WHERE state=1") if err != nil { @@ -621,7 +623,7 @@ func upgradeV0_4_7(db *dbs.DB) error { // v0.4.8 func upgradeV0_4_8(db *dbs.DB) error { - // 设置edgeIPLists中的serverId + // 璁剧疆edgeIPLists涓殑serverId { firewallPolicyOnes, _, err := db.FindOnes("SELECT inbound,serverId FROM edgeHTTPFirewallPolicies WHERE serverId>0") if err != nil { @@ -673,7 +675,7 @@ func upgradeV0_4_8(db *dbs.DB) error { // v0.4.11 func upgradeV0_4_11(db *dbs.DB) error { - // 升级ns端口 + // 鍗囩骇ns绔彛 { // TCP { @@ -751,19 +753,19 @@ func upgradeV1_2_1(db *dbs.DB) error { // 1.2.10 func upgradeV1_2_10(db *dbs.DB) error { { - type OldGlobalConfig struct { - // HTTP & HTTPS相关配置 - HTTPAll struct { - DomainAuditingIsOn bool `yaml:"domainAuditingIsOn" json:"domainAuditingIsOn"` // 域名是否需要审核 - DomainAuditingPrompt string `yaml:"domainAuditingPrompt" json:"domainAuditingPrompt"` // 域名审核的提示 - } `yaml:"httpAll" json:"httpAll"` + type OldGlobalConfig struct { + // HTTP & HTTPS鐩稿叧閰嶇疆 + HTTPAll struct { + DomainAuditingIsOn bool `yaml:"domainAuditingIsOn" json:"domainAuditingIsOn"` // 域名是否需要审核 + DomainAuditingPrompt string `yaml:"domainAuditingPrompt" json:"domainAuditingPrompt"` // 域名审核提示 + } `yaml:"httpAll" json:"httpAll"` - TCPAll struct { - PortRangeMin int `yaml:"portRangeMin" json:"portRangeMin"` // 最小端口 - PortRangeMax int `yaml:"portRangeMax" json:"portRangeMax"` // 最大端口 - DenyPorts []int `yaml:"denyPorts" json:"denyPorts"` // 禁止使用的端口 - } `yaml:"tcpAll" json:"tcpAll"` - } + TCPAll struct { + PortRangeMin int `yaml:"portRangeMin" json:"portRangeMin"` // 最小端口 + PortRangeMax int `yaml:"portRangeMax" json:"portRangeMax"` // 最大端口 + DenyPorts []int `yaml:"denyPorts" json:"denyPorts"` // 禁止端口 + } `yaml:"tcpAll" json:"tcpAll"` + } globalConfigValue, err := db.FindCol(0, "SELECT value FROM edgeSysSettings WHERE code='serverGlobalConfig'") if err != nil { @@ -1023,7 +1025,7 @@ func upgradeV1_3_2(db *dbs.DB) error { } } - err = addRuleToGroup(ruleGroup.GetInt64("id"), "7010", "SQL注入检测", []*firewallconfigs.HTTPFirewallActionConfig{ + err = addRuleToGroup(ruleGroup.GetInt64("id"), "7010", "SQL注入检测", []*firewallconfigs.HTTPFirewallActionConfig{ { Code: firewallconfigs.HTTPFirewallActionPage, Options: maps.Map{"status": 403, "body": ""}, @@ -1131,7 +1133,7 @@ func upgradeV1_3_2(db *dbs.DB) error { } } - err = addRuleToGroup(ruleGroup.GetInt64("id"), "1010", "XSS攻击检测", []*firewallconfigs.HTTPFirewallActionConfig{ + err = addRuleToGroup(ruleGroup.GetInt64("id"), "1010", "XSS攻击检测", []*firewallconfigs.HTTPFirewallActionConfig{ { Code: firewallconfigs.HTTPFirewallActionPage, Options: maps.Map{"status": 403, "body": ""}, @@ -1233,8 +1235,8 @@ func upgradeV1_3_4(db *dbs.DB) error { // 1.4.4 func upgradeV1_4_4(db *dbs.DB) error { - // 检查 encryption 字段是否已存在 - col, err := db.FindCol(0, "SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='edgeHTTPWebs' AND COLUMN_NAME='encryption'") + // 检查 encryption 字段是否已存在 + col, err := db.FindCol(0, "SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='edgeHTTPWebs' AND COLUMN_NAME='encryption'") if err != nil { return err } @@ -1253,3 +1255,30 @@ func upgradeV1_4_4(db *dbs.DB) error { return nil } + +// 1.4.8 +func upgradeV1_4_8(db *dbs.DB) error { + return createHTTPDNSTables(db) +} + +func createHTTPDNSTables(db *dbs.DB) error { + sqls := []string{ + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSClusters` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`isDefault` tinyint unsigned DEFAULT '0',`serviceDomain` varchar(255) DEFAULT NULL,`defaultTTL` int unsigned DEFAULT '30',`fallbackTimeoutMs` int unsigned DEFAULT '300',`installDir` varchar(255) DEFAULT '/opt/edge-httpdns',`tlsPolicy` json DEFAULT NULL,`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),KEY `name` (`name`),KEY `isDefault` (`isDefault`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS集群配置表(默认TTL、回退超时、服务域名等)'", + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSNodes` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`clusterId` bigint unsigned DEFAULT '0',`name` varchar(255) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`isUp` tinyint unsigned DEFAULT '0',`isInstalled` tinyint unsigned DEFAULT '0',`isActive` tinyint unsigned DEFAULT '0',`uniqueId` varchar(64) DEFAULT NULL,`secret` varchar(64) DEFAULT NULL,`installDir` varchar(255) DEFAULT '/opt/edge-httpdns',`status` json DEFAULT NULL,`installStatus` json DEFAULT NULL,`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `uniqueId` (`uniqueId`),KEY `clusterId` (`clusterId`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS节点表(节点基础信息与运行状态)'", + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSApps` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`appId` varchar(64) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`primaryClusterId` bigint unsigned DEFAULT '0',`backupClusterId` bigint unsigned DEFAULT '0',`sniMode` varchar(64) DEFAULT 'fixed_hide',`userId` bigint unsigned DEFAULT '0',`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `appId` (`appId`),KEY `name` (`name`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS应用表(应用与主备集群绑定关系)'", + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSAppSecrets` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`appId` bigint unsigned DEFAULT '0',`signEnabled` tinyint unsigned DEFAULT '0',`signSecret` varchar(255) DEFAULT NULL,`signUpdatedAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `appId` (`appId`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS应用密钥表(请求验签开关与加签Secret)'", + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSDomains` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`appId` bigint unsigned DEFAULT '0',`domain` varchar(255) DEFAULT NULL,`isOn` tinyint unsigned DEFAULT '1',`createdAt` bigint unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),UNIQUE KEY `appId_domain` (`appId`,`domain`),KEY `domain` (`domain`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS应用域名表(应用绑定的业务域名)'", + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSCustomRules` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`appId` bigint unsigned DEFAULT '0',`domainId` bigint unsigned DEFAULT '0',`ruleName` varchar(255) DEFAULT NULL,`lineScope` varchar(64) DEFAULT NULL,`lineCarrier` varchar(64) DEFAULT NULL,`lineRegion` varchar(64) DEFAULT NULL,`lineProvince` varchar(64) DEFAULT NULL,`lineContinent` varchar(64) DEFAULT NULL,`lineCountry` varchar(128) DEFAULT NULL,`ttl` int unsigned DEFAULT '30',`isOn` tinyint unsigned DEFAULT '1',`priority` int unsigned DEFAULT '0',`updatedAt` bigint unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),KEY `domainId_isOn_priority` (`domainId`,`isOn`,`priority`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS自定义解析规则表(按线路/地域匹配)'", + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSCustomRuleRecords` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`ruleId` bigint unsigned DEFAULT '0',`recordType` varchar(32) DEFAULT NULL,`recordValue` varchar(255) DEFAULT NULL,`weight` int unsigned DEFAULT '0',`sort` int unsigned DEFAULT '0',`state` tinyint unsigned DEFAULT '1',PRIMARY KEY (`id`),KEY `ruleId` (`ruleId`),KEY `state` (`state`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS自定义规则记录值表(A/AAAA及权重)'", + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSAccessLogs` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`requestId` varchar(128) DEFAULT NULL,`clusterId` bigint unsigned DEFAULT '0',`nodeId` bigint unsigned DEFAULT '0',`appId` varchar(64) DEFAULT NULL,`appName` varchar(255) DEFAULT NULL,`domain` varchar(255) DEFAULT NULL,`qtype` varchar(16) DEFAULT NULL,`clientIP` varchar(64) DEFAULT NULL,`clientRegion` varchar(255) DEFAULT NULL,`carrier` varchar(128) DEFAULT NULL,`sdkVersion` varchar(64) DEFAULT NULL,`os` varchar(64) DEFAULT NULL,`resultIPs` text,`status` varchar(32) DEFAULT NULL,`errorCode` varchar(64) DEFAULT NULL,`costMs` int unsigned DEFAULT '0',`createdAt` bigint unsigned DEFAULT '0',`day` varchar(8) DEFAULT NULL,`summary` text,PRIMARY KEY (`id`),UNIQUE KEY `requestId_nodeId` (`requestId`,`nodeId`),KEY `day_cluster_node_domain_status_createdAt` (`day`,`clusterId`,`nodeId`,`domain`,`status`,`createdAt`),KEY `appId` (`appId`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS访问日志表(解析请求与结果)'", + "CREATE TABLE IF NOT EXISTS `edgeHTTPDNSRuntimeLogs` (`id` bigint unsigned NOT NULL AUTO_INCREMENT,`clusterId` bigint unsigned DEFAULT '0',`nodeId` bigint unsigned DEFAULT '0',`level` varchar(32) DEFAULT NULL,`type` varchar(64) DEFAULT NULL,`module` varchar(64) DEFAULT NULL,`description` text,`count` bigint unsigned DEFAULT '1',`requestId` varchar(128) DEFAULT NULL,`createdAt` bigint unsigned DEFAULT '0',`day` varchar(8) DEFAULT NULL,PRIMARY KEY (`id`),KEY `day_cluster_node_level_createdAt` (`day`,`clusterId`,`nodeId`,`level`,`createdAt`),KEY `requestId` (`requestId`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='HTTPDNS运行日志表(节点运行与异常日志)'", + } + for _, sql := range sqls { + if _, err := db.Exec(sql); err != nil { + return err + } + } + return nil +} + + diff --git a/EdgeAPI/internal/tasks/node_task_extractor.go b/EdgeAPI/internal/tasks/node_task_extractor.go index 99b6567..82b4bbc 100644 --- a/EdgeAPI/internal/tasks/node_task_extractor.go +++ b/EdgeAPI/internal/tasks/node_task_extractor.go @@ -46,7 +46,7 @@ func (this *NodeTaskExtractor) Loop() error { // 这里不解锁,是为了让任务N秒钟之内只运行一次 - for _, role := range []string{nodeconfigs.NodeRoleNode, nodeconfigs.NodeRoleDNS} { + for _, role := range []string{nodeconfigs.NodeRoleNode, nodeconfigs.NodeRoleDNS, nodeconfigs.NodeRoleHTTPDNS} { err := models.SharedNodeTaskDAO.ExtractAllClusterTasks(nil, role) if err != nil { return err diff --git a/EdgeAdmin/internal/const/const.go b/EdgeAdmin/internal/const/const.go index fb41589..2d7b7e8 100644 --- a/EdgeAdmin/internal/const/const.go +++ b/EdgeAdmin/internal/const/const.go @@ -1,9 +1,9 @@ package teaconst const ( - Version = "1.4.7" //1.3.9 + Version = "1.4.8" //1.3.9 - APINodeVersion = "1.4.7" //1.3.9 + APINodeVersion = "1.4.8" //1.3.9 ProductName = "Edge Admin" ProcessName = "edge-admin" diff --git a/EdgeAdmin/internal/rpc/rpc_client.go b/EdgeAdmin/internal/rpc/rpc_client.go index 753a4e7..0bd112c 100644 --- a/EdgeAdmin/internal/rpc/rpc_client.go +++ b/EdgeAdmin/internal/rpc/rpc_client.go @@ -349,6 +349,38 @@ func (this *RPCClient) DNSTaskRPC() pb.DNSTaskServiceClient { return pb.NewDNSTaskServiceClient(this.pickConn()) } +func (this *RPCClient) HTTPDNSClusterRPC() pb.HTTPDNSClusterServiceClient { + return pb.NewHTTPDNSClusterServiceClient(this.pickConn()) +} + +func (this *RPCClient) HTTPDNSNodeRPC() pb.HTTPDNSNodeServiceClient { + return pb.NewHTTPDNSNodeServiceClient(this.pickConn()) +} + +func (this *RPCClient) HTTPDNSAppRPC() pb.HTTPDNSAppServiceClient { + return pb.NewHTTPDNSAppServiceClient(this.pickConn()) +} + +func (this *RPCClient) HTTPDNSDomainRPC() pb.HTTPDNSDomainServiceClient { + return pb.NewHTTPDNSDomainServiceClient(this.pickConn()) +} + +func (this *RPCClient) HTTPDNSRuleRPC() pb.HTTPDNSRuleServiceClient { + return pb.NewHTTPDNSRuleServiceClient(this.pickConn()) +} + +func (this *RPCClient) HTTPDNSAccessLogRPC() pb.HTTPDNSAccessLogServiceClient { + return pb.NewHTTPDNSAccessLogServiceClient(this.pickConn()) +} + +func (this *RPCClient) HTTPDNSRuntimeLogRPC() pb.HTTPDNSRuntimeLogServiceClient { + return pb.NewHTTPDNSRuntimeLogServiceClient(this.pickConn()) +} + +func (this *RPCClient) HTTPDNSSandboxRPC() pb.HTTPDNSSandboxServiceClient { + return pb.NewHTTPDNSSandboxServiceClient(this.pickConn()) +} + func (this *RPCClient) ACMEUserRPC() pb.ACMEUserServiceClient { return pb.NewACMEUserServiceClient(this.pickConn()) } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/app.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/app.go index 7a19ee8..2d4a89b 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/app.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/app.go @@ -17,6 +17,10 @@ func (this *AppAction) Init() { func (this *AppAction) RunGet(params struct { AppId int64 }) { - app := pickApp(params.AppId) + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } this.RedirectURL("/httpdns/apps/domains?appId=" + strconv.FormatInt(app.GetInt64("id"), 10)) } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettings.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettings.go index 7a1e314..6304160 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettings.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettings.go @@ -5,8 +5,9 @@ import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/policies" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" + "github.com/iwind/TeaGo/maps" ) type AppSettingsAction struct { @@ -22,33 +23,45 @@ func (this *AppSettingsAction) RunGet(params struct { Section string }) { httpdnsutils.AddLeftMenu(this.Parent()) - app := pickApp(params.AppId) - // 顶部 tabbar - httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), params.AppId, "settings") + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } + + httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), app.GetInt64("id"), "settings") - // 当前选中的 section section := params.Section if len(section) == 0 { section = "basic" } this.Data["activeSection"] = section - appIdStr := strconv.FormatInt(params.AppId, 10) - this.Data["leftMenuItems"] = []map[string]interface{}{ + + appIDStr := strconv.FormatInt(app.GetInt64("id"), 10) + this.Data["leftMenuItems"] = []maps.Map{ { "name": "基础配置", - "url": "/httpdns/apps/app/settings?appId=" + appIdStr + "§ion=basic", + "url": "/httpdns/apps/app/settings?appId=" + appIDStr + "§ion=basic", "isActive": section == "basic", }, { "name": "认证与密钥", - "url": "/httpdns/apps/app/settings?appId=" + appIdStr + "§ion=auth", + "url": "/httpdns/apps/app/settings?appId=" + appIDStr + "§ion=auth", "isActive": section == "auth", }, } - settings := loadAppSettings(app) - this.Data["clusters"] = policies.LoadAvailableDeployClusters() + settings := maps.Map{ + "appId": app.GetString("appId"), + "appStatus": app.GetBool("isOn"), + "primaryClusterId": app.GetInt64("primaryClusterId"), + "backupClusterId": app.GetInt64("backupClusterId"), + "signEnabled": app.GetBool("signEnabled"), + "signSecretPlain": app.GetString("signSecretPlain"), + "signSecretMasked": app.GetString("signSecretMasked"), + "signSecretUpdatedAt": app.GetString("signSecretUpdated"), + } this.Data["app"] = app this.Data["settings"] = settings this.Show() @@ -57,36 +70,37 @@ func (this *AppSettingsAction) RunGet(params struct { func (this *AppSettingsAction) RunPost(params struct { AppId int64 - AppStatus bool - PrimaryClusterId int64 - BackupClusterId int64 + AppStatus bool Must *actions.Must CSRF *actionutils.CSRF }) { - params.Must.Field("appId", params.AppId).Gt(0, "please select app") - params.Must.Field("primaryClusterId", params.PrimaryClusterId).Gt(0, "please select primary cluster") - if params.BackupClusterId > 0 && params.BackupClusterId == params.PrimaryClusterId { - this.FailField("backupClusterId", "backup cluster must be different from primary cluster") + params.Must.Field("appId", params.AppId).Gt(0, "请选择应用") + + appResp, err := this.RPC().HTTPDNSAppRPC().FindHTTPDNSApp(this.AdminContext(), &pb.FindHTTPDNSAppRequest{ + AppDbId: params.AppId, + }) + if err != nil { + this.ErrorPage(err) + return + } + if appResp.GetApp() == nil { + this.Fail("找不到对应的应用") + return } - app := pickApp(params.AppId) - settings := loadAppSettings(app) - settings["appStatus"] = params.AppStatus - settings["primaryClusterId"] = params.PrimaryClusterId - settings["backupClusterId"] = params.BackupClusterId + _, err = this.RPC().HTTPDNSAppRPC().UpdateHTTPDNSApp(this.AdminContext(), &pb.UpdateHTTPDNSAppRequest{ + AppDbId: params.AppId, + Name: appResp.GetApp().GetName(), + PrimaryClusterId: appResp.GetApp().GetPrimaryClusterId(), + BackupClusterId: appResp.GetApp().GetBackupClusterId(), + IsOn: params.AppStatus, + UserId: appResp.GetApp().GetUserId(), + }) + if err != nil { + this.ErrorPage(err) + return + } - // SNI strategy is fixed to level2 empty. - settings["sniPolicy"] = "level2" - settings["level2Mode"] = "empty" - settings["publicSniDomain"] = "" - settings["echFallbackPolicy"] = "level2" - settings["ecsMode"] = "off" - settings["ecsIPv4Prefix"] = 24 - settings["ecsIPv6Prefix"] = 56 - settings["pinningMode"] = "off" - settings["sanMode"] = "off" - - saveAppSettings(app.GetInt64("id"), settings) this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettingsResetSignSecret.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettingsResetSignSecret.go index c1391e2..a282c5d 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettingsResetSignSecret.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettingsResetSignSecret.go @@ -2,6 +2,7 @@ package apps import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" ) @@ -13,11 +14,16 @@ func (this *AppSettingsResetSignSecretAction) RunPost(params struct { AppId int64 Must *actions.Must - CSRF *actionutils.CSRF }) { params.Must.Field("appId", params.AppId).Gt(0, "请选择应用") - app := pickApp(params.AppId) - resetSignSecret(app) + _, err := this.RPC().HTTPDNSAppRPC().ResetHTTPDNSAppSignSecret(this.AdminContext(), &pb.ResetHTTPDNSAppSignSecretRequest{ + AppDbId: params.AppId, + }) + if err != nil { + this.ErrorPage(err) + return + } + this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettingsToggleSignEnabled.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettingsToggleSignEnabled.go index 6b86394..57b9225 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettingsToggleSignEnabled.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettingsToggleSignEnabled.go @@ -2,6 +2,7 @@ package apps import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" ) @@ -14,14 +15,17 @@ func (this *AppSettingsToggleSignEnabledAction) RunPost(params struct { IsOn int Must *actions.Must - CSRF *actionutils.CSRF }) { params.Must.Field("appId", params.AppId).Gt(0, "请选择应用") - app := pickApp(params.AppId) - settings := loadAppSettings(app) - settings["signEnabled"] = params.IsOn == 1 - saveAppSettings(app.GetInt64("id"), settings) + _, err := this.RPC().HTTPDNSAppRPC().UpdateHTTPDNSAppSignEnabled(this.AdminContext(), &pb.UpdateHTTPDNSAppSignEnabledRequest{ + AppDbId: params.AppId, + SignEnabled: params.IsOn == 1, + }) + if err != nil { + this.ErrorPage(err) + return + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettings_store.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettings_store.go deleted file mode 100644 index 4c327a2..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/appSettings_store.go +++ /dev/null @@ -1,223 +0,0 @@ -package apps - -import ( - "fmt" - "sync" - "time" - - "github.com/iwind/TeaGo/maps" -) - -var appSettingsStore = struct { - sync.RWMutex - data map[int64]maps.Map -}{ - data: map[int64]maps.Map{}, -} - -func defaultAppSettings(app maps.Map) maps.Map { - signSecretPlain := randomPlainSecret("ss") - return maps.Map{ - "appId": app.GetString("appId"), - "primaryClusterId": app.GetInt64("clusterId"), - "backupClusterId": int64(0), - "signSecretPlain": signSecretPlain, - "signSecretMasked": maskSecret(signSecretPlain), - "signSecretUpdatedAt": "2026-02-20 12:30:00", - "appStatus": app.GetBool("isOn"), - "defaultTTL": 30, - "fallbackTimeoutMs": 300, - "sniPolicy": "level2", - "level2Mode": "empty", - "publicSniDomain": "", - "echFallbackPolicy": "level2", - "ecsMode": "off", - "ecsIPv4Prefix": 24, - "ecsIPv6Prefix": 56, - "pinningMode": "off", - "sanMode": "off", - "signEnabled": true, - } -} - -func cloneSettings(settings maps.Map) maps.Map { - return maps.Map{ - "appId": settings.GetString("appId"), - "primaryClusterId": settings.GetInt64("primaryClusterId"), - "backupClusterId": settings.GetInt64("backupClusterId"), - "signSecretPlain": settings.GetString("signSecretPlain"), - "signSecretMasked": settings.GetString("signSecretMasked"), - "signSecretUpdatedAt": settings.GetString("signSecretUpdatedAt"), - "appStatus": settings.GetBool("appStatus"), - "defaultTTL": settings.GetInt("defaultTTL"), - "fallbackTimeoutMs": settings.GetInt("fallbackTimeoutMs"), - "sniPolicy": settings.GetString("sniPolicy"), - "level2Mode": settings.GetString("level2Mode"), - "publicSniDomain": settings.GetString("publicSniDomain"), - "echFallbackPolicy": settings.GetString("echFallbackPolicy"), - "ecsMode": settings.GetString("ecsMode"), - "ecsIPv4Prefix": settings.GetInt("ecsIPv4Prefix"), - "ecsIPv6Prefix": settings.GetInt("ecsIPv6Prefix"), - "pinningMode": settings.GetString("pinningMode"), - "sanMode": settings.GetString("sanMode"), - "signEnabled": settings.GetBool("signEnabled"), - } -} - -func loadAppSettings(app maps.Map) maps.Map { - appId := app.GetInt64("id") - appSettingsStore.RLock() - settings, ok := appSettingsStore.data[appId] - appSettingsStore.RUnlock() - if ok { - if ensureSettingsFields(settings) { - saveAppSettings(appId, settings) - } - return cloneSettings(settings) - } - - settings = defaultAppSettings(app) - saveAppSettings(appId, settings) - return cloneSettings(settings) -} - -func saveAppSettings(appId int64, settings maps.Map) { - appSettingsStore.Lock() - appSettingsStore.data[appId] = cloneSettings(settings) - appSettingsStore.Unlock() -} - -func deleteAppSettings(appId int64) { - appSettingsStore.Lock() - delete(appSettingsStore.data, appId) - appSettingsStore.Unlock() -} - -func resetSignSecret(app maps.Map) maps.Map { - settings := loadAppSettings(app) - signSecretPlain := randomPlainSecret("ss") - settings["signSecretPlain"] = signSecretPlain - settings["signSecretMasked"] = maskSecret(signSecretPlain) - settings["signSecretUpdatedAt"] = nowDateTime() - saveAppSettings(app.GetInt64("id"), settings) - return settings -} - -func nowDateTime() string { - return time.Now().Format("2006-01-02 15:04:05") -} - -func randomPlainSecret(prefix string) string { - suffix := time.Now().UnixNano() & 0xffff - return fmt.Sprintf("%s_%016x", prefix, suffix) -} - -func maskSecret(secret string) string { - if len(secret) < 4 { - return "******" - } - - prefix := "" - for i := 0; i < len(secret); i++ { - if secret[i] == '_' { - prefix = secret[:i+1] - break - } - } - if len(prefix) == 0 { - prefix = secret[:2] - } - - if len(secret) <= 8 { - return prefix + "xxxx" - } - return prefix + "xxxxxxxx" + secret[len(secret)-4:] -} - -func ensureSettingsFields(settings maps.Map) bool { - changed := false - - if settings.GetInt64("primaryClusterId") <= 0 { - settings["primaryClusterId"] = int64(1) - changed = true - } - if settings.GetInt64("backupClusterId") < 0 { - settings["backupClusterId"] = int64(0) - changed = true - } - if settings.GetInt64("backupClusterId") > 0 && settings.GetInt64("backupClusterId") == settings.GetInt64("primaryClusterId") { - settings["backupClusterId"] = int64(0) - changed = true - } - - signSecretPlain := settings.GetString("signSecretPlain") - if len(signSecretPlain) == 0 { - signSecretPlain = randomPlainSecret("ss") - settings["signSecretPlain"] = signSecretPlain - changed = true - } - if len(settings.GetString("signSecretMasked")) == 0 { - settings["signSecretMasked"] = maskSecret(signSecretPlain) - changed = true - } - if len(settings.GetString("signSecretUpdatedAt")) == 0 { - settings["signSecretUpdatedAt"] = nowDateTime() - changed = true - } - - if len(settings.GetString("sniPolicy")) == 0 { - settings["sniPolicy"] = "level2" - changed = true - } else if settings.GetString("sniPolicy") != "level2" { - settings["sniPolicy"] = "level2" - changed = true - } - if settings.GetString("level2Mode") != "empty" { - settings["level2Mode"] = "empty" - changed = true - } - if len(settings.GetString("publicSniDomain")) > 0 { - settings["publicSniDomain"] = "" - changed = true - } - if len(settings.GetString("echFallbackPolicy")) == 0 { - settings["echFallbackPolicy"] = "level2" - changed = true - } else if settings.GetString("echFallbackPolicy") != "level2" { - settings["echFallbackPolicy"] = "level2" - changed = true - } - if settings.GetString("ecsMode") != "off" { - settings["ecsMode"] = "off" - changed = true - } - if settings.GetInt("ecsIPv4Prefix") <= 0 { - settings["ecsIPv4Prefix"] = 24 - changed = true - } - if settings.GetInt("ecsIPv6Prefix") <= 0 { - settings["ecsIPv6Prefix"] = 56 - changed = true - } - if settings.GetString("pinningMode") != "off" { - settings["pinningMode"] = "off" - changed = true - } - if settings.GetString("sanMode") != "off" { - settings["sanMode"] = "off" - changed = true - } - - return changed -} - -// LoadAppSettingsByAppID exposes app settings for other httpdns sub-modules -// such as sandbox mock responses. -func LoadAppSettingsByAppID(appID string) maps.Map { - for _, app := range mockApps() { - if app.GetString("appId") == appID { - return loadAppSettings(app) - } - } - return nil -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/create.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/create.go new file mode 100644 index 0000000..4b734ce --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/create.go @@ -0,0 +1,92 @@ +package apps + +import ( + "strconv" + "time" + + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/actions" + "github.com/iwind/TeaGo/maps" +) + +type CreateAction struct { + actionutils.ParentAction +} + +func (this *CreateAction) Init() { + this.Nav("", "", "create") +} + +func (this *CreateAction) RunGet(params struct{}) { + clusterResp, err := this.RPC().HTTPDNSClusterRPC().FindAllHTTPDNSClusters(this.AdminContext(), &pb.FindAllHTTPDNSClustersRequest{}) + if err != nil { + this.ErrorPage(err) + return + } + clusters := make([]maps.Map, 0, len(clusterResp.GetClusters())) + for _, cluster := range clusterResp.GetClusters() { + clusters = append(clusters, maps.Map{ + "id": cluster.GetId(), + "name": cluster.GetName(), + }) + } + this.Data["clusters"] = clusters + + defaultPrimaryClusterId := int64(0) + for _, cluster := range clusterResp.GetClusters() { + if cluster.GetIsDefault() { + defaultPrimaryClusterId = cluster.GetId() + break + } + } + if defaultPrimaryClusterId <= 0 && len(clusters) > 0 { + defaultPrimaryClusterId = clusters[0].GetInt64("id") + } + this.Data["defaultPrimaryClusterId"] = defaultPrimaryClusterId + + defaultBackupClusterId := int64(0) + for _, cluster := range clusters { + clusterId := cluster.GetInt64("id") + if clusterId > 0 && clusterId != defaultPrimaryClusterId { + defaultBackupClusterId = clusterId + break + } + } + this.Data["defaultBackupClusterId"] = defaultBackupClusterId + + this.Show() +} + +func (this *CreateAction) RunPost(params struct { + Name string + PrimaryClusterId int64 + BackupClusterId int64 + UserId int64 + + Must *actions.Must + CSRF *actionutils.CSRF +}) { + params.Must.Field("name", params.Name).Require("请输入应用名称") + params.Must.Field("primaryClusterId", params.PrimaryClusterId).Gt(0, "请输入主服务集群") + if params.BackupClusterId > 0 && params.BackupClusterId == params.PrimaryClusterId { + this.FailField("backupClusterId", "备用服务集群必须和主服务集群不一致") + } + + createResp, err := this.RPC().HTTPDNSAppRPC().CreateHTTPDNSApp(this.AdminContext(), &pb.CreateHTTPDNSAppRequest{ + Name: params.Name, + AppId: "app" + strconv.FormatInt(time.Now().UnixNano()%1_000_000_000_000, 36), + PrimaryClusterId: params.PrimaryClusterId, + BackupClusterId: params.BackupClusterId, + IsOn: true, + SignEnabled: true, + UserId: params.UserId, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Data["appId"] = createResp.GetAppDbId() + this.Success() +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/createPopup.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/createPopup.go deleted file mode 100644 index a71a42c..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/createPopup.go +++ /dev/null @@ -1,63 +0,0 @@ -package apps - -import ( - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/policies" - "github.com/iwind/TeaGo/actions" - "github.com/iwind/TeaGo/maps" -) - -type CreatePopupAction struct { - actionutils.ParentAction -} - -func (this *CreatePopupAction) Init() { - this.Nav("", "", "") -} - -func (this *CreatePopupAction) RunGet(params struct{}) { - clusters := policies.LoadAvailableDeployClusters() - this.Data["clusters"] = clusters - - defaultPrimaryClusterId := policies.LoadDefaultClusterID() - if defaultPrimaryClusterId <= 0 && len(clusters) > 0 { - defaultPrimaryClusterId = clusters[0].GetInt64("id") - } - this.Data["defaultPrimaryClusterId"] = defaultPrimaryClusterId - - defaultBackupClusterId := int64(0) - for _, cluster := range clusters { - clusterId := cluster.GetInt64("id") - if clusterId > 0 && clusterId != defaultPrimaryClusterId { - defaultBackupClusterId = clusterId - break - } - } - this.Data["defaultBackupClusterId"] = defaultBackupClusterId - - // Mock users for dropdown - this.Data["users"] = []maps.Map{ - {"id": int64(1), "name": "User A", "username": "zhangsan"}, - {"id": int64(2), "name": "User B", "username": "lisi"}, - {"id": int64(3), "name": "User C", "username": "wangwu"}, - } - - this.Show() -} - -func (this *CreatePopupAction) RunPost(params struct { - Name string - PrimaryClusterId int64 - BackupClusterId int64 - UserId int64 - - Must *actions.Must - CSRF *actionutils.CSRF -}) { - params.Must.Field("name", params.Name).Require("please input app name") - params.Must.Field("primaryClusterId", params.PrimaryClusterId).Gt(0, "please select primary cluster") - if params.BackupClusterId > 0 && params.BackupClusterId == params.PrimaryClusterId { - this.FailField("backupClusterId", "backup cluster must be different from primary cluster") - } - this.Success() -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecords.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecords.go index 1257bf1..19a75bd 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecords.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecords.go @@ -20,25 +20,32 @@ func (this *CustomRecordsAction) RunGet(params struct { }) { httpdnsutils.AddLeftMenu(this.Parent()) - app := pickApp(params.AppId) - // 自定义解析属于域名管理子页,顶部沿用应用 tabbar(高亮域名列表) - httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), params.AppId, "domains") + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } + httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), app.GetInt64("id"), "domains") - domains := mockDomains(app.GetInt64("id")) - domain := pickDomainFromDomains(domains, params.DomainId) - domainName := domain.GetString("name") + domains, err := listDomainMaps(this.Parent(), app.GetInt64("id"), "") + if err != nil { + this.ErrorPage(err) + return + } + domain := findDomainMap(domains, params.DomainId) records := make([]maps.Map, 0) - for _, record := range loadCustomRecords(app.GetInt64("id")) { - if len(domainName) > 0 && record.GetString("domain") != domainName { - continue + if domain.GetInt64("id") > 0 { + records, err = listCustomRuleMaps(this.Parent(), domain.GetInt64("id")) + if err != nil { + this.ErrorPage(err) + return + } + for _, record := range records { + record["domain"] = domain.GetString("name") + record["lineText"] = buildLineText(record) + record["recordValueText"] = buildRecordValueText(record) } - records = append(records, record) - } - - for _, record := range records { - record["lineText"] = buildLineText(record) - record["recordValueText"] = buildRecordValueText(record) } this.Data["app"] = app @@ -47,17 +54,3 @@ func (this *CustomRecordsAction) RunGet(params struct { this.Show() } -func pickDomainFromDomains(domains []maps.Map, domainID int64) maps.Map { - if len(domains) == 0 { - return maps.Map{} - } - if domainID <= 0 { - return domains[0] - } - for _, domain := range domains { - if domain.GetInt64("id") == domainID { - return domain - } - } - return domains[0] -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsCreatePopup.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsCreatePopup.go index 22d6d63..93c1638 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsCreatePopup.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsCreatePopup.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/maps" ) @@ -23,11 +24,18 @@ func (this *CustomRecordsCreatePopupAction) RunGet(params struct { DomainId int64 RecordId int64 }) { - app := pickApp(params.AppId) - this.Data["app"] = app - domains := mockDomains(app.GetInt64("id")) - domain := pickDomainFromDomains(domains, params.DomainId) - this.Data["domain"] = domain + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } + + domains, err := listDomainMaps(this.Parent(), app.GetInt64("id"), "") + if err != nil { + this.ErrorPage(err) + return + } + domain := findDomainMap(domains, params.DomainId) record := maps.Map{ "id": int64(0), @@ -45,77 +53,35 @@ func (this *CustomRecordsCreatePopupAction) RunGet(params struct { "recordItemsJson": `[{"type":"A","value":"","weight":100}]`, } - if params.RecordId > 0 { - existing := findCustomRecord(app.GetInt64("id"), params.RecordId) - if len(existing) > 0 { - record["id"] = existing.GetInt64("id") - if len(record.GetString("domain")) == 0 { - record["domain"] = existing.GetString("domain") + if params.RecordId > 0 && domain.GetInt64("id") > 0 { + rules, err := listCustomRuleMaps(this.Parent(), domain.GetInt64("id")) + if err != nil { + this.ErrorPage(err) + return + } + for _, rule := range rules { + if rule.GetInt64("id") != params.RecordId { + continue } - - record["lineScope"] = strings.TrimSpace(existing.GetString("lineScope")) - record["lineCarrier"] = strings.TrimSpace(existing.GetString("lineCarrier")) - record["lineRegion"] = strings.TrimSpace(existing.GetString("lineRegion")) - record["lineProvince"] = strings.TrimSpace(existing.GetString("lineProvince")) - record["lineContinent"] = strings.TrimSpace(existing.GetString("lineContinent")) - record["lineCountry"] = strings.TrimSpace(existing.GetString("lineCountry")) - record["ruleName"] = existing.GetString("ruleName") - record["weightEnabled"] = existing.GetBool("weightEnabled") - record["ttl"] = existing.GetInt("ttl") - record["isOn"] = existing.GetBool("isOn") - - recordItems := make([]maps.Map, 0) - recordType := strings.ToUpper(strings.TrimSpace(existing.GetString("recordType"))) - values, _ := existing["recordValues"].([]maps.Map) - for _, item := range values { - itemType := strings.ToUpper(strings.TrimSpace(item.GetString("type"))) - if len(itemType) == 0 { - itemType = recordType - } - if itemType != "A" && itemType != "AAAA" { - itemType = "A" - } - - recordItems = append(recordItems, maps.Map{ - "type": itemType, - "value": strings.TrimSpace(item.GetString("value")), - "weight": item.GetInt("weight"), - }) - } - if len(recordItems) == 0 { - recordItems = append(recordItems, maps.Map{ - "type": "A", - "value": "", - "weight": 100, - }) - } - record["recordItemsJson"] = marshalJSON(recordItems, "[]") + record["id"] = rule.GetInt64("id") + record["domain"] = domain.GetString("name") + record["lineScope"] = rule.GetString("lineScope") + record["lineCarrier"] = defaultLineField(rule.GetString("lineCarrier")) + record["lineRegion"] = defaultLineField(rule.GetString("lineRegion")) + record["lineProvince"] = defaultLineField(rule.GetString("lineProvince")) + record["lineContinent"] = defaultLineField(rule.GetString("lineContinent")) + record["lineCountry"] = defaultLineField(rule.GetString("lineCountry")) + record["ruleName"] = rule.GetString("ruleName") + record["weightEnabled"] = rule.GetBool("weightEnabled") + record["ttl"] = rule.GetInt("ttl") + record["isOn"] = rule.GetBool("isOn") + record["recordItemsJson"] = marshalJSON(rule["recordValues"], "[]") + break } } - if record.GetString("lineScope") != "china" && record.GetString("lineScope") != "overseas" { - if len(strings.TrimSpace(record.GetString("lineContinent"))) > 0 || len(strings.TrimSpace(record.GetString("lineCountry"))) > 0 { - record["lineScope"] = "overseas" - } else { - record["lineScope"] = "china" - } - } - if len(record.GetString("lineCarrier")) == 0 { - record["lineCarrier"] = "默认" - } - if len(record.GetString("lineRegion")) == 0 { - record["lineRegion"] = "默认" - } - if len(record.GetString("lineProvince")) == 0 { - record["lineProvince"] = "默认" - } - if len(record.GetString("lineContinent")) == 0 { - record["lineContinent"] = "默认" - } - if len(record.GetString("lineCountry")) == 0 { - record["lineCountry"] = "默认" - } - + this.Data["app"] = app + this.Data["domain"] = domain this.Data["record"] = record this.Data["isEditing"] = params.RecordId > 0 this.Show() @@ -138,40 +104,26 @@ func (this *CustomRecordsCreatePopupAction) RunPost(params struct { RuleName string RecordItemsJSON string WeightEnabled bool - TTL int + Ttl int IsOn bool Must *actions.Must CSRF *actionutils.CSRF }) { - params.Must.Field("appId", params.AppId).Gt(0, "please select app") + params.Must.Field("appId", params.AppId).Gt(0, "请选择应用") + params.Must.Field("domainId", params.DomainId).Gt(0, "请选择所属域名") - params.Domain = strings.TrimSpace(params.Domain) params.LineScope = strings.ToLower(strings.TrimSpace(params.LineScope)) - params.RuleName = strings.TrimSpace(params.RuleName) - params.RecordItemsJSON = strings.TrimSpace(params.RecordItemsJSON) - - domain := maps.Map{} - if params.DomainId > 0 { - domain = pickDomainFromDomains(mockDomains(params.AppId), params.DomainId) - } - if len(domain) > 0 { - params.Domain = strings.TrimSpace(domain.GetString("name")) - } - if len(params.Domain) == 0 { - this.Fail("please select domain") - return - } - if params.LineScope != "china" && params.LineScope != "overseas" { params.LineScope = "china" } + params.RuleName = strings.TrimSpace(params.RuleName) if len(params.RuleName) == 0 { - this.Fail("please input rule name") + this.Fail("请输入规则名称") return } - if params.TTL <= 0 || params.TTL > 86400 { - this.Fail("ttl should be in 1-86400") + if params.Ttl <= 0 || params.Ttl > 86400 { + this.Fail("TTL值必须在 1-86400 范围内") return } @@ -181,11 +133,11 @@ func (this *CustomRecordsCreatePopupAction) RunPost(params struct { return } if len(recordValues) == 0 { - this.Fail("please input record values") + this.Fail("请输入解析记录值") return } if len(recordValues) > 10 { - this.Fail("record values should be <= 10") + this.Fail("单个规则最多只能添加 10 条解析记录") return } @@ -209,7 +161,6 @@ func (this *CustomRecordsCreatePopupAction) RunPost(params struct { if len(lineCountry) == 0 { lineCountry = "默认" } - if params.LineScope == "overseas" { lineCarrier = "" lineRegion = "" @@ -219,40 +170,57 @@ func (this *CustomRecordsCreatePopupAction) RunPost(params struct { lineCountry = "" } - recordType := recordValues[0].GetString("type") - if len(recordType) == 0 { - recordType = "A" + records := make([]*pb.HTTPDNSRuleRecord, 0, len(recordValues)) + for i, item := range recordValues { + records = append(records, &pb.HTTPDNSRuleRecord{ + Id: 0, + RuleId: 0, + RecordType: item.GetString("type"), + RecordValue: item.GetString("value"), + Weight: int32(item.GetInt("weight")), + Sort: int32(i + 1), + }) } - saveCustomRecord(params.AppId, maps.Map{ - "id": params.RecordId, - "domain": params.Domain, - "lineScope": params.LineScope, - "lineCarrier": lineCarrier, - "lineRegion": lineRegion, - "lineProvince": lineProvince, - "lineContinent": lineContinent, - "lineCountry": lineCountry, - "ruleName": params.RuleName, - "sdnsParams": []maps.Map{}, - "recordType": recordType, - "recordValues": recordValues, - "weightEnabled": params.WeightEnabled, - "ttl": params.TTL, - "isOn": params.IsOn, - }) + rule := &pb.HTTPDNSCustomRule{ + Id: params.RecordId, + AppId: params.AppId, + DomainId: params.DomainId, + RuleName: params.RuleName, + LineScope: params.LineScope, + LineCarrier: lineCarrier, + LineRegion: lineRegion, + LineProvince: lineProvince, + LineContinent: lineContinent, + LineCountry: lineCountry, + Ttl: int32(params.Ttl), + IsOn: params.IsOn, + Priority: 100, + Records: records, + } + + if params.RecordId > 0 { + err = updateCustomRule(this.Parent(), rule) + } else { + _, err = createCustomRule(this.Parent(), rule) + } + if err != nil { + this.ErrorPage(err) + return + } this.Success() } func parseRecordItemsJSON(raw string, weightEnabled bool) ([]maps.Map, error) { + raw = strings.TrimSpace(raw) if len(raw) == 0 { return []maps.Map{}, nil } list := []maps.Map{} if err := json.Unmarshal([]byte(raw), &list); err != nil { - return nil, fmt.Errorf("record items json is invalid") + return nil, fmt.Errorf("解析记录格式不正确") } result := make([]maps.Map, 0, len(list)) @@ -263,10 +231,10 @@ func parseRecordItemsJSON(raw string, weightEnabled bool) ([]maps.Map, error) { continue } if recordType != "A" && recordType != "AAAA" { - return nil, fmt.Errorf("record type should be A or AAAA") + return nil, fmt.Errorf("记录类型只能是 A 或 AAAA") } if len(recordValue) == 0 { - return nil, fmt.Errorf("record value should not be empty") + return nil, fmt.Errorf("记录值不能为空") } weight := item.GetInt("weight") @@ -274,7 +242,7 @@ func parseRecordItemsJSON(raw string, weightEnabled bool) ([]maps.Map, error) { weight = 100 } if weight < 1 || weight > 100 { - return nil, fmt.Errorf("weight should be in 1-100") + return nil, fmt.Errorf("权重值必须在 1-100 之间") } result = append(result, maps.Map{ @@ -283,7 +251,6 @@ func parseRecordItemsJSON(raw string, weightEnabled bool) ([]maps.Map, error) { "weight": weight, }) } - return result, nil } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsDelete.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsDelete.go index 4d8777c..27fed65 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsDelete.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsDelete.go @@ -10,8 +10,12 @@ func (this *CustomRecordsDeleteAction) RunPost(params struct { AppId int64 RecordId int64 }) { - if params.AppId > 0 && params.RecordId > 0 { - deleteCustomRecord(params.AppId, params.RecordId) + if params.RecordId > 0 { + err := deleteCustomRule(this.Parent(), params.RecordId) + if err != nil { + this.ErrorPage(err) + return + } } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsToggle.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsToggle.go index 0e16fd3..8504532 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsToggle.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/customRecordsToggle.go @@ -11,8 +11,12 @@ func (this *CustomRecordsToggleAction) RunPost(params struct { RecordId int64 IsOn bool }) { - if params.AppId > 0 && params.RecordId > 0 { - toggleCustomRecord(params.AppId, params.RecordId, params.IsOn) + if params.RecordId > 0 { + err := toggleCustomRule(this.Parent(), params.RecordId, params.IsOn) + if err != nil { + this.ErrorPage(err) + return + } } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/custom_records_store.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/custom_records_store.go deleted file mode 100644 index d0419d1..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/custom_records_store.go +++ /dev/null @@ -1,244 +0,0 @@ -package apps - -import ( - "strconv" - "strings" - "sync" - "time" - - "github.com/iwind/TeaGo/maps" -) - -var customRecordStore = struct { - sync.RWMutex - nextID int64 - data map[int64][]maps.Map -}{ - nextID: 1000, - data: map[int64][]maps.Map{ - 1: { - { - "id": int64(1001), - "domain": "api.business.com", - "lineScope": "china", - "lineCarrier": "电信", - "lineRegion": "华东", - "lineProvince": "上海", - "ruleName": "上海电信灰度-v2", - "sdnsParams": []maps.Map{}, - "recordType": "A", - "recordValues": []maps.Map{{"type": "A", "value": "1.1.1.10", "weight": 100}}, - "weightEnabled": false, - "ttl": 30, - "isOn": true, - "updatedAt": "2026-02-23 10:20:00", - }, - }, - }, -} - -func loadCustomRecords(appID int64) []maps.Map { - customRecordStore.RLock() - defer customRecordStore.RUnlock() - - records := customRecordStore.data[appID] - result := make([]maps.Map, 0, len(records)) - for _, record := range records { - result = append(result, cloneCustomRecord(record)) - } - return result -} - -func countCustomRecordsByDomain(appID int64, domain string) int { - domain = strings.ToLower(strings.TrimSpace(domain)) - if len(domain) == 0 { - return 0 - } - - customRecordStore.RLock() - defer customRecordStore.RUnlock() - - count := 0 - for _, record := range customRecordStore.data[appID] { - if strings.ToLower(strings.TrimSpace(record.GetString("domain"))) == domain { - count++ - } - } - return count -} - -func findCustomRecord(appID int64, recordID int64) maps.Map { - for _, record := range loadCustomRecords(appID) { - if record.GetInt64("id") == recordID { - return record - } - } - return maps.Map{} -} - -func saveCustomRecord(appID int64, record maps.Map) maps.Map { - customRecordStore.Lock() - defer customRecordStore.Unlock() - - if appID <= 0 { - return maps.Map{} - } - - record = cloneCustomRecord(record) - recordID := record.GetInt64("id") - if recordID <= 0 { - customRecordStore.nextID++ - recordID = customRecordStore.nextID - record["id"] = recordID - } - record["updatedAt"] = nowCustomRecordTime() - - records := customRecordStore.data[appID] - found := false - for i, oldRecord := range records { - if oldRecord.GetInt64("id") == recordID { - records[i] = cloneCustomRecord(record) - found = true - break - } - } - if !found { - records = append(records, cloneCustomRecord(record)) - } - customRecordStore.data[appID] = records - - return cloneCustomRecord(record) -} - -func deleteCustomRecord(appID int64, recordID int64) { - customRecordStore.Lock() - defer customRecordStore.Unlock() - - records := customRecordStore.data[appID] - if len(records) == 0 { - return - } - - filtered := make([]maps.Map, 0, len(records)) - for _, record := range records { - if record.GetInt64("id") == recordID { - continue - } - filtered = append(filtered, record) - } - customRecordStore.data[appID] = filtered -} - -func deleteCustomRecordsByApp(appID int64) { - customRecordStore.Lock() - defer customRecordStore.Unlock() - delete(customRecordStore.data, appID) -} - -func toggleCustomRecord(appID int64, recordID int64, isOn bool) { - customRecordStore.Lock() - defer customRecordStore.Unlock() - - records := customRecordStore.data[appID] - for i, record := range records { - if record.GetInt64("id") == recordID { - record["isOn"] = isOn - record["updatedAt"] = nowCustomRecordTime() - records[i] = record - break - } - } - customRecordStore.data[appID] = records -} - -func cloneCustomRecord(src maps.Map) maps.Map { - dst := maps.Map{} - for k, v := range src { - switch k { - case "sdnsParams", "recordValues": - if list, ok := v.([]maps.Map); ok { - cloned := make([]maps.Map, 0, len(list)) - for _, item := range list { - m := maps.Map{} - for k2, v2 := range item { - m[k2] = v2 - } - cloned = append(cloned, m) - } - dst[k] = cloned - } else { - dst[k] = []maps.Map{} - } - default: - dst[k] = v - } - } - return dst -} - -func nowCustomRecordTime() string { - return time.Now().Format("2006-01-02 15:04:05") -} - -func buildLineText(record maps.Map) string { - parts := []string{} - if strings.TrimSpace(record.GetString("lineScope")) == "overseas" { - parts = append(parts, - strings.TrimSpace(record.GetString("lineContinent")), - strings.TrimSpace(record.GetString("lineCountry")), - ) - } else { - parts = append(parts, - strings.TrimSpace(record.GetString("lineCarrier")), - strings.TrimSpace(record.GetString("lineRegion")), - strings.TrimSpace(record.GetString("lineProvince")), - ) - } - - finalParts := make([]string, 0, len(parts)) - for _, part := range parts { - if len(part) == 0 || part == "默认" { - continue - } - finalParts = append(finalParts, part) - } - if len(finalParts) == 0 { - return "默认" - } - return strings.Join(finalParts, " / ") -} - -func buildRecordValueText(record maps.Map) string { - values, ok := record["recordValues"].([]maps.Map) - if !ok || len(values) == 0 { - return "-" - } - - weightEnabled := record.GetBool("weightEnabled") - defaultType := strings.ToUpper(strings.TrimSpace(record.GetString("recordType"))) - parts := make([]string, 0, len(values)) - for _, item := range values { - value := strings.TrimSpace(item.GetString("value")) - if len(value) == 0 { - continue - } - recordType := strings.ToUpper(strings.TrimSpace(item.GetString("type"))) - if len(recordType) == 0 { - recordType = defaultType - } - if recordType != "A" && recordType != "AAAA" { - recordType = "A" - } - part := recordType + " " + value - if weightEnabled { - part += "(" + strconv.Itoa(item.GetInt("weight")) + ")" - } else { - // no extra suffix - } - parts = append(parts, part) - } - if len(parts) == 0 { - return "-" - } - return strings.Join(parts, ", ") -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/delete.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/delete.go index 6ce6c19..004fe45 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/delete.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/delete.go @@ -17,10 +17,19 @@ func (this *DeleteAction) RunGet(params struct { AppId int64 }) { httpdnsutils.AddLeftMenu(this.Parent()) - app := pickApp(params.AppId) + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), app.GetInt64("id"), "delete") this.Data["app"] = app - this.Data["domainCount"] = len(mockDomains(app.GetInt64("id"))) + domains, err := listDomainMaps(this.Parent(), app.GetInt64("id"), "") + if err != nil { + this.ErrorPage(err) + return + } + this.Data["domainCount"] = len(domains) this.Show() } @@ -28,9 +37,10 @@ func (this *DeleteAction) RunPost(params struct { AppId int64 }) { if params.AppId > 0 { - if deleteApp(params.AppId) { - deleteAppSettings(params.AppId) - deleteCustomRecordsByApp(params.AppId) + err := deleteAppByID(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return } } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/domains.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/domains.go index 08ef685..576de1a 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/domains.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/domains.go @@ -17,15 +17,19 @@ func (this *DomainsAction) RunGet(params struct { AppId int64 }) { httpdnsutils.AddLeftMenu(this.Parent()) - app := pickApp(params.AppId) + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } // 构建顶部 tabbar httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), params.AppId, "domains") - domains := mockDomains(app.GetInt64("id")) - for _, domain := range domains { - domainName := domain.GetString("name") - domain["customRecordCount"] = countCustomRecordsByDomain(app.GetInt64("id"), domainName) + domains, err := listDomainMaps(this.Parent(), app.GetInt64("id"), "") + if err != nil { + this.ErrorPage(err) + return } this.Data["app"] = app diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/domainsCreatePopup.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/domainsCreatePopup.go index ef26367..44cc478 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/domainsCreatePopup.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/domainsCreatePopup.go @@ -16,7 +16,12 @@ func (this *DomainsCreatePopupAction) Init() { func (this *DomainsCreatePopupAction) RunGet(params struct { AppId int64 }) { - this.Data["app"] = pickApp(params.AppId) + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["app"] = app this.Show() } @@ -27,6 +32,13 @@ func (this *DomainsCreatePopupAction) RunPost(params struct { Must *actions.Must CSRF *actionutils.CSRF }) { - params.Must.Field("domain", params.Domain).Require("please input domain") + params.Must.Field("appId", params.AppId).Gt(0, "请选择应用") + params.Must.Field("domain", params.Domain).Require("请输入域名") + + err := createDomain(this.Parent(), params.AppId, params.Domain) + if err != nil { + this.ErrorPage(err) + return + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/domainsDelete.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/domainsDelete.go index 8bd72d4..67042c3 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/domainsDelete.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/domainsDelete.go @@ -9,6 +9,12 @@ type DomainsDeleteAction struct { func (this *DomainsDeleteAction) RunPost(params struct { DomainId int64 }) { - _ = params.DomainId + if params.DomainId > 0 { + err := deleteDomain(this.Parent(), params.DomainId) + if err != nil { + this.ErrorPage(err) + return + } + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/formatters.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/formatters.go new file mode 100644 index 0000000..5c52256 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/formatters.go @@ -0,0 +1,92 @@ +package apps + +import ( + "strconv" + "strings" + + "github.com/iwind/TeaGo/maps" +) + +func maskSecret(secret string) string { + secret = strings.TrimSpace(secret) + if len(secret) < 4 { + return "******" + } + + prefix := "" + for i := 0; i < len(secret); i++ { + if secret[i] == '_' { + prefix = secret[:i+1] + break + } + } + if len(prefix) == 0 { + prefix = secret[:2] + } + + if len(secret) <= 8 { + return prefix + "xxxx" + } + return prefix + "xxxxxxxx" + secret[len(secret)-4:] +} + +func buildLineText(record maps.Map) string { + parts := []string{} + if strings.TrimSpace(record.GetString("lineScope")) == "overseas" { + parts = append(parts, + strings.TrimSpace(record.GetString("lineContinent")), + strings.TrimSpace(record.GetString("lineCountry")), + ) + } else { + parts = append(parts, + strings.TrimSpace(record.GetString("lineCarrier")), + strings.TrimSpace(record.GetString("lineRegion")), + strings.TrimSpace(record.GetString("lineProvince")), + ) + } + + finalParts := make([]string, 0, len(parts)) + for _, part := range parts { + if len(part) == 0 || part == "默认" { + continue + } + finalParts = append(finalParts, part) + } + if len(finalParts) == 0 { + return "默认" + } + return strings.Join(finalParts, " / ") +} + +func buildRecordValueText(record maps.Map) string { + values, ok := record["recordValues"].([]maps.Map) + if !ok || len(values) == 0 { + return "-" + } + + weightEnabled := record.GetBool("weightEnabled") + defaultType := strings.ToUpper(strings.TrimSpace(record.GetString("recordType"))) + parts := make([]string, 0, len(values)) + for _, item := range values { + value := strings.TrimSpace(item.GetString("value")) + if len(value) == 0 { + continue + } + recordType := strings.ToUpper(strings.TrimSpace(item.GetString("type"))) + if len(recordType) == 0 { + recordType = defaultType + } + if recordType != "A" && recordType != "AAAA" { + recordType = "A" + } + part := recordType + " " + value + if weightEnabled { + part += "(" + strconv.Itoa(item.GetInt("weight")) + ")" + } + parts = append(parts, part) + } + if len(parts) == 0 { + return "-" + } + return strings.Join(parts, ", ") +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/index.go index bb17da6..232d390 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/index.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/index.go @@ -18,6 +18,11 @@ func (this *IndexAction) RunGet(params struct { }) { httpdnsutils.AddLeftMenu(this.Parent()) this.Data["keyword"] = params.Keyword - this.Data["apps"] = filterApps(params.Keyword, "", "", "") + apps, err := listAppMaps(this.Parent(), params.Keyword) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["apps"] = apps this.Show() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/init.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/init.go index d9db84b..e705574 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/init.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/init.go @@ -15,13 +15,17 @@ func init() { Prefix("/httpdns/apps"). Get("", new(IndexAction)). Get("/app", new(AppAction)). - Get("/sdk", new(SDKAction)). + Get("/sdk", new(SdkAction)). + GetPost("/sdk/upload", new(SdkUploadAction)). + Post("/sdk/upload/delete", new(SdkUploadDeleteAction)). + Get("/sdk/download", new(SdkDownloadAction)). + Get("/sdk/doc", new(SdkDocAction)). GetPost("/app/settings", new(AppSettingsAction)). Post("/app/settings/toggleSignEnabled", new(AppSettingsToggleSignEnabledAction)). Post("/app/settings/resetSignSecret", new(AppSettingsResetSignSecretAction)). Get("/domains", new(DomainsAction)). Get("/customRecords", new(CustomRecordsAction)). - GetPost("/createPopup", new(CreatePopupAction)). + GetPost("/create", new(CreateAction)). GetPost("/delete", new(DeleteAction)). GetPost("/domains/createPopup", new(DomainsCreatePopupAction)). Post("/domains/delete", new(DomainsDeleteAction)). diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/mock.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/mock.go deleted file mode 100644 index 0587dd5..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/mock.go +++ /dev/null @@ -1,190 +0,0 @@ -package apps - -import ( - "strings" - "sync" - - "github.com/iwind/TeaGo/maps" -) - -var appStore = struct { - sync.RWMutex - data []maps.Map -}{ - data: defaultMockApps(), -} - -func defaultMockApps() []maps.Map { - return []maps.Map{ - { - "id": int64(1), - "name": "\u4e3b\u7ad9\u79fb\u52a8\u4e1a\u52a1", - "appId": "ab12xc34s2", - "clusterId": int64(1), - "domainCount": 3, - "isOn": true, - "authStatus": "enabled", - "ecsMode": "auto", - "pinningMode": "report", - "sanMode": "strict", - "riskLevel": "medium", - "riskSummary": "Pinning \u5904\u4e8e\u89c2\u5bdf\u6a21\u5f0f", - "secretVersion": "v2026.02.20", - }, - { - "id": int64(2), - "name": "\u89c6\u9891\u7f51\u5173\u4e1a\u52a1", - "appId": "vd8992ksm1", - "clusterId": int64(2), - "domainCount": 1, - "isOn": true, - "authStatus": "enabled", - "ecsMode": "custom", - "pinningMode": "enforce", - "sanMode": "strict", - "riskLevel": "low", - "riskSummary": "\u5df2\u542f\u7528\u5f3a\u6821\u9a8c", - "secretVersion": "v2026.02.18", - }, - { - "id": int64(3), - "name": "\u6d77\u5916\u7070\u5ea6\u6d4b\u8bd5", - "appId": "ov7711hkq9", - "clusterId": int64(1), - "domainCount": 2, - "isOn": false, - "authStatus": "disabled", - "ecsMode": "off", - "pinningMode": "off", - "sanMode": "report", - "riskLevel": "high", - "riskSummary": "\u5e94\u7528\u5173\u95ed\u4e14\u8bc1\u4e66\u7b56\u7565\u504f\u5f31", - "secretVersion": "v2026.01.30", - }, - } -} - -func cloneMap(src maps.Map) maps.Map { - dst := maps.Map{} - for k, v := range src { - dst[k] = v - } - return dst -} - -func cloneApps(apps []maps.Map) []maps.Map { - result := make([]maps.Map, 0, len(apps)) - for _, app := range apps { - result = append(result, cloneMap(app)) - } - return result -} - -func mockApps() []maps.Map { - appStore.RLock() - defer appStore.RUnlock() - return cloneApps(appStore.data) -} - -func deleteApp(appID int64) bool { - if appID <= 0 { - return false - } - - appStore.Lock() - defer appStore.Unlock() - - found := false - filtered := make([]maps.Map, 0, len(appStore.data)) - for _, app := range appStore.data { - if app.GetInt64("id") == appID { - found = true - continue - } - filtered = append(filtered, app) - } - if found { - appStore.data = filtered - } - return found -} - -func filterApps(keyword string, riskLevel string, ecsMode string, pinningMode string) []maps.Map { - all := mockApps() - if len(keyword) == 0 && len(riskLevel) == 0 && len(ecsMode) == 0 && len(pinningMode) == 0 { - return all - } - - keyword = strings.ToLower(strings.TrimSpace(keyword)) - result := make([]maps.Map, 0) - for _, app := range all { - if len(keyword) > 0 { - name := strings.ToLower(app.GetString("name")) - appID := strings.ToLower(app.GetString("appId")) - if !strings.Contains(name, keyword) && !strings.Contains(appID, keyword) { - continue - } - } - if len(riskLevel) > 0 && app.GetString("riskLevel") != riskLevel { - continue - } - if len(ecsMode) > 0 && app.GetString("ecsMode") != ecsMode { - continue - } - if len(pinningMode) > 0 && app.GetString("pinningMode") != pinningMode { - continue - } - result = append(result, app) - } - - return result -} - -func pickApp(appID int64) maps.Map { - apps := mockApps() - if len(apps) == 0 { - return maps.Map{ - "id": int64(0), - "name": "", - "appId": "", - "clusterId": int64(0), - } - } - - if appID <= 0 { - return apps[0] - } - for _, app := range apps { - if app.GetInt64("id") == appID { - return app - } - } - return apps[0] -} - -func mockDomains(appID int64) []maps.Map { - _ = appID - return []maps.Map{ - { - "id": int64(101), - "name": "api.business.com", - }, - { - "id": int64(102), - "name": "payment.business.com", - }, - } -} - -func pickDomain(domainID int64) maps.Map { - domains := mockDomains(0) - if domainID <= 0 { - return domains[0] - } - for _, domain := range domains { - if domain.GetInt64("id") == domainID { - return domain - } - } - return domains[0] -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/policies.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/policies.go deleted file mode 100644 index 36c5296..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/policies.go +++ /dev/null @@ -1,85 +0,0 @@ -package apps - -import ( - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" - "github.com/iwind/TeaGo/actions" - "github.com/iwind/TeaGo/maps" -) - -type PoliciesAction struct { - actionutils.ParentAction -} - -func (this *PoliciesAction) Init() { - this.Nav("httpdns", "app", "") -} - -func (this *PoliciesAction) RunGet(params struct{}) { - httpdnsutils.AddLeftMenu(this.Parent()) - this.Data["policies"] = loadGlobalPolicies() - this.Show() -} - -func (this *PoliciesAction) RunPost(params struct { - DefaultTTL int - DefaultSniPolicy string - DefaultFallbackMs int - ECSMode string - ECSIPv4Prefix int - ECSIPv6Prefix int - PinningMode string - SANMode string - - Must *actions.Must - CSRF *actionutils.CSRF -}) { - params.Must.Field("defaultTTL", params.DefaultTTL).Gt(0, "默认 TTL 需要大于 0") - params.Must.Field("defaultFallbackMs", params.DefaultFallbackMs).Gt(0, "默认超时需要大于 0") - - if params.DefaultTTL > 86400 { - this.Fail("默认 TTL 不能超过 86400 秒") - return - } - if params.DefaultFallbackMs > 10000 { - this.Fail("默认超时不能超过 10000 毫秒") - return - } - if params.DefaultSniPolicy != "level1" && params.DefaultSniPolicy != "level2" && params.DefaultSniPolicy != "level3" { - this.Fail("默认 SNI 等级不正确") - return - } - if params.ECSMode != "off" && params.ECSMode != "auto" && params.ECSMode != "custom" { - this.Fail("ECS 模式不正确") - return - } - if params.ECSIPv4Prefix < 0 || params.ECSIPv4Prefix > 32 { - this.Fail("IPv4 掩码范围是 0-32") - return - } - if params.ECSIPv6Prefix < 0 || params.ECSIPv6Prefix > 128 { - this.Fail("IPv6 掩码范围是 0-128") - return - } - if params.PinningMode != "off" && params.PinningMode != "report" && params.PinningMode != "enforce" { - this.Fail("Pinning 策略不正确") - return - } - if params.SANMode != "off" && params.SANMode != "report" && params.SANMode != "strict" { - this.Fail("SAN 策略不正确") - return - } - - saveGlobalPolicies(maps.Map{ - "defaultTTL": params.DefaultTTL, - "defaultSniPolicy": params.DefaultSniPolicy, - "defaultFallbackMs": params.DefaultFallbackMs, - "ecsMode": params.ECSMode, - "ecsIPv4Prefix": params.ECSIPv4Prefix, - "ecsIPv6Prefix": params.ECSIPv6Prefix, - "pinningMode": params.PinningMode, - "sanMode": params.SANMode, - }) - - this.Success() -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/policies_store.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/policies_store.go deleted file mode 100644 index 08aee8f..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/policies_store.go +++ /dev/null @@ -1,54 +0,0 @@ -package apps - -import ( - "sync" - - "github.com/iwind/TeaGo/maps" -) - -var globalPoliciesStore = struct { - sync.RWMutex - data maps.Map -}{ - data: maps.Map{ - "defaultTTL": 30, - "defaultSniPolicy": "level2", - "defaultFallbackMs": 300, - "ecsMode": "auto", - "ecsIPv4Prefix": 24, - "ecsIPv6Prefix": 56, - "pinningMode": "report", - "sanMode": "strict", - }, -} - -func loadGlobalPolicies() maps.Map { - globalPoliciesStore.RLock() - defer globalPoliciesStore.RUnlock() - - return maps.Map{ - "defaultTTL": globalPoliciesStore.data.GetInt("defaultTTL"), - "defaultSniPolicy": globalPoliciesStore.data.GetString("defaultSniPolicy"), - "defaultFallbackMs": globalPoliciesStore.data.GetInt("defaultFallbackMs"), - "ecsMode": globalPoliciesStore.data.GetString("ecsMode"), - "ecsIPv4Prefix": globalPoliciesStore.data.GetInt("ecsIPv4Prefix"), - "ecsIPv6Prefix": globalPoliciesStore.data.GetInt("ecsIPv6Prefix"), - "pinningMode": globalPoliciesStore.data.GetString("pinningMode"), - "sanMode": globalPoliciesStore.data.GetString("sanMode"), - } -} - -func saveGlobalPolicies(policies maps.Map) { - globalPoliciesStore.Lock() - globalPoliciesStore.data = maps.Map{ - "defaultTTL": policies.GetInt("defaultTTL"), - "defaultSniPolicy": policies.GetString("defaultSniPolicy"), - "defaultFallbackMs": policies.GetInt("defaultFallbackMs"), - "ecsMode": policies.GetString("ecsMode"), - "ecsIPv4Prefix": policies.GetInt("ecsIPv4Prefix"), - "ecsIPv6Prefix": policies.GetInt("ecsIPv6Prefix"), - "pinningMode": policies.GetString("pinningMode"), - "sanMode": policies.GetString("sanMode"), - } - globalPoliciesStore.Unlock() -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/rpc_helpers.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/rpc_helpers.go new file mode 100644 index 0000000..dddb9f4 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/rpc_helpers.go @@ -0,0 +1,295 @@ +package apps + +import ( + "strconv" + "strings" + "time" + + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + timeutil "github.com/iwind/TeaGo/utils/time" + "github.com/iwind/TeaGo/maps" +) + +func listAppMaps(parent *actionutils.ParentAction, keyword string) ([]maps.Map, error) { + resp, err := parent.RPC().HTTPDNSAppRPC().ListHTTPDNSApps(parent.AdminContext(), &pb.ListHTTPDNSAppsRequest{ + Offset: 0, + Size: 10_000, + Keyword: strings.TrimSpace(keyword), + }) + if err != nil { + return nil, err + } + + result := make([]maps.Map, 0, len(resp.GetApps())) + for _, app := range resp.GetApps() { + domainResp, err := parent.RPC().HTTPDNSDomainRPC().ListHTTPDNSDomainsWithAppId(parent.AdminContext(), &pb.ListHTTPDNSDomainsWithAppIdRequest{ + AppDbId: app.GetId(), + }) + if err != nil { + return nil, err + } + + result = append(result, appPBToMap(app, int64(len(domainResp.GetDomains())))) + } + + return result, nil +} + +func findAppMap(parent *actionutils.ParentAction, appDbId int64) (maps.Map, error) { + if appDbId > 0 { + resp, err := parent.RPC().HTTPDNSAppRPC().FindHTTPDNSApp(parent.AdminContext(), &pb.FindHTTPDNSAppRequest{ + AppDbId: appDbId, + }) + if err != nil { + return nil, err + } + if resp.GetApp() != nil { + domainResp, err := parent.RPC().HTTPDNSDomainRPC().ListHTTPDNSDomainsWithAppId(parent.AdminContext(), &pb.ListHTTPDNSDomainsWithAppIdRequest{ + AppDbId: appDbId, + }) + if err != nil { + return nil, err + } + return appPBToMap(resp.GetApp(), int64(len(domainResp.GetDomains()))), nil + } + } + + apps, err := listAppMaps(parent, "") + if err != nil { + return nil, err + } + if len(apps) == 0 { + return maps.Map{ + "id": int64(0), + "name": "", + "appId": "", + }, nil + } + return apps[0], nil +} + +func createApp(parent *actionutils.ParentAction, name string, primaryClusterId int64, backupClusterId int64) (int64, error) { + newAppId := "app" + strconv.FormatInt(time.Now().UnixNano()%1_000_000_000_000, 36) + resp, err := parent.RPC().HTTPDNSAppRPC().CreateHTTPDNSApp(parent.AdminContext(), &pb.CreateHTTPDNSAppRequest{ + Name: strings.TrimSpace(name), + AppId: newAppId, + PrimaryClusterId: primaryClusterId, + BackupClusterId: backupClusterId, + IsOn: true, + SignEnabled: true, + }) + if err != nil { + return 0, err + } + return resp.GetAppDbId(), nil +} + +func deleteAppByID(parent *actionutils.ParentAction, appDbId int64) error { + _, err := parent.RPC().HTTPDNSAppRPC().DeleteHTTPDNSApp(parent.AdminContext(), &pb.DeleteHTTPDNSAppRequest{ + AppDbId: appDbId, + }) + return err +} + +func updateAppSettings(parent *actionutils.ParentAction, appDbId int64, name string, primaryClusterId int64, backupClusterId int64, isOn bool, userId int64) error { + _, err := parent.RPC().HTTPDNSAppRPC().UpdateHTTPDNSApp(parent.AdminContext(), &pb.UpdateHTTPDNSAppRequest{ + AppDbId: appDbId, + Name: strings.TrimSpace(name), + PrimaryClusterId: primaryClusterId, + BackupClusterId: backupClusterId, + IsOn: isOn, + UserId: userId, + }) + return err +} + +func updateAppSignEnabled(parent *actionutils.ParentAction, appDbId int64, signEnabled bool) error { + _, err := parent.RPC().HTTPDNSAppRPC().UpdateHTTPDNSAppSignEnabled(parent.AdminContext(), &pb.UpdateHTTPDNSAppSignEnabledRequest{ + AppDbId: appDbId, + SignEnabled: signEnabled, + }) + return err +} + +func resetAppSignSecret(parent *actionutils.ParentAction, appDbId int64) (*pb.ResetHTTPDNSAppSignSecretResponse, error) { + return parent.RPC().HTTPDNSAppRPC().ResetHTTPDNSAppSignSecret(parent.AdminContext(), &pb.ResetHTTPDNSAppSignSecretRequest{ + AppDbId: appDbId, + }) +} + +func listDomainMaps(parent *actionutils.ParentAction, appDbId int64, keyword string) ([]maps.Map, error) { + resp, err := parent.RPC().HTTPDNSDomainRPC().ListHTTPDNSDomainsWithAppId(parent.AdminContext(), &pb.ListHTTPDNSDomainsWithAppIdRequest{ + AppDbId: appDbId, + Keyword: strings.TrimSpace(keyword), + }) + if err != nil { + return nil, err + } + + result := make([]maps.Map, 0, len(resp.GetDomains())) + for _, domain := range resp.GetDomains() { + result = append(result, maps.Map{ + "id": domain.GetId(), + "name": domain.GetDomain(), + "isOn": domain.GetIsOn(), + "customRecordCount": domain.GetRuleCount(), + }) + } + return result, nil +} + +func createDomain(parent *actionutils.ParentAction, appDbId int64, domain string) error { + _, err := parent.RPC().HTTPDNSDomainRPC().CreateHTTPDNSDomain(parent.AdminContext(), &pb.CreateHTTPDNSDomainRequest{ + AppDbId: appDbId, + Domain: strings.TrimSpace(domain), + IsOn: true, + }) + return err +} + +func deleteDomain(parent *actionutils.ParentAction, domainId int64) error { + _, err := parent.RPC().HTTPDNSDomainRPC().DeleteHTTPDNSDomain(parent.AdminContext(), &pb.DeleteHTTPDNSDomainRequest{ + DomainId: domainId, + }) + return err +} + +func findDomainMap(domains []maps.Map, domainID int64) maps.Map { + if len(domains) == 0 { + return maps.Map{} + } + if domainID <= 0 { + return domains[0] + } + for _, domain := range domains { + if domain.GetInt64("id") == domainID { + return domain + } + } + return domains[0] +} + +func listCustomRuleMaps(parent *actionutils.ParentAction, domainId int64) ([]maps.Map, error) { + resp, err := parent.RPC().HTTPDNSRuleRPC().ListHTTPDNSCustomRulesWithDomainId(parent.AdminContext(), &pb.ListHTTPDNSCustomRulesWithDomainIdRequest{ + DomainId: domainId, + }) + if err != nil { + return nil, err + } + + result := make([]maps.Map, 0, len(resp.GetRules())) + for _, rule := range resp.GetRules() { + recordValues := make([]maps.Map, 0, len(rule.GetRecords())) + recordType := "A" + weightEnabled := false + for _, record := range rule.GetRecords() { + if len(recordType) == 0 { + recordType = strings.ToUpper(strings.TrimSpace(record.GetRecordType())) + } + if record.GetWeight() > 0 && record.GetWeight() != 100 { + weightEnabled = true + } + recordValues = append(recordValues, maps.Map{ + "type": strings.ToUpper(strings.TrimSpace(record.GetRecordType())), + "value": record.GetRecordValue(), + "weight": record.GetWeight(), + }) + } + if len(recordValues) == 0 { + recordValues = append(recordValues, maps.Map{ + "type": "A", + "value": "", + "weight": 100, + }) + } + + item := maps.Map{ + "id": rule.GetId(), + "lineScope": rule.GetLineScope(), + "lineCarrier": defaultLineField(rule.GetLineCarrier()), + "lineRegion": defaultLineField(rule.GetLineRegion()), + "lineProvince": defaultLineField(rule.GetLineProvince()), + "lineContinent": defaultLineField(rule.GetLineContinent()), + "lineCountry": defaultLineField(rule.GetLineCountry()), + "ruleName": rule.GetRuleName(), + "recordType": recordType, + "recordValues": recordValues, + "weightEnabled": weightEnabled, + "ttl": rule.GetTtl(), + "isOn": rule.GetIsOn(), + "updatedAt": formatDateTime(rule.GetUpdatedAt()), + } + item["lineText"] = buildLineText(item) + item["recordValueText"] = buildRecordValueText(item) + result = append(result, item) + } + return result, nil +} + +func createCustomRule(parent *actionutils.ParentAction, rule *pb.HTTPDNSCustomRule) (int64, error) { + resp, err := parent.RPC().HTTPDNSRuleRPC().CreateHTTPDNSCustomRule(parent.AdminContext(), &pb.CreateHTTPDNSCustomRuleRequest{ + Rule: rule, + }) + if err != nil { + return 0, err + } + return resp.GetRuleId(), nil +} + +func updateCustomRule(parent *actionutils.ParentAction, rule *pb.HTTPDNSCustomRule) error { + _, err := parent.RPC().HTTPDNSRuleRPC().UpdateHTTPDNSCustomRule(parent.AdminContext(), &pb.UpdateHTTPDNSCustomRuleRequest{ + Rule: rule, + }) + return err +} + +func deleteCustomRule(parent *actionutils.ParentAction, ruleId int64) error { + _, err := parent.RPC().HTTPDNSRuleRPC().DeleteHTTPDNSCustomRule(parent.AdminContext(), &pb.DeleteHTTPDNSCustomRuleRequest{ + RuleId: ruleId, + }) + return err +} + +func toggleCustomRule(parent *actionutils.ParentAction, ruleId int64, isOn bool) error { + _, err := parent.RPC().HTTPDNSRuleRPC().UpdateHTTPDNSCustomRuleStatus(parent.AdminContext(), &pb.UpdateHTTPDNSCustomRuleStatusRequest{ + RuleId: ruleId, + IsOn: isOn, + }) + return err +} + +func appPBToMap(app *pb.HTTPDNSApp, domainCount int64) maps.Map { + signSecret := app.GetSignSecret() + return maps.Map{ + "id": app.GetId(), + "name": app.GetName(), + "appId": app.GetAppId(), + "clusterId": app.GetPrimaryClusterId(), + "primaryClusterId": app.GetPrimaryClusterId(), + "backupClusterId": app.GetBackupClusterId(), + "userId": app.GetUserId(), + "isOn": app.GetIsOn(), + "domainCount": domainCount, + "sniPolicyText": "隐匿 SNI", + "signEnabled": app.GetSignEnabled(), + "signSecretPlain": signSecret, + "signSecretMasked": maskSecret(signSecret), + "signSecretUpdated": formatDateTime(app.GetSignUpdatedAt()), + } +} + +func defaultLineField(value string) string { + value = strings.TrimSpace(value) + if len(value) == 0 { + return "默认" + } + return value +} + +func formatDateTime(ts int64) string { + if ts <= 0 { + return "" + } + return timeutil.FormatTime("Y-m-d H:i:s", ts) +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk.go index ddeda94..95a2509 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk.go @@ -5,23 +5,26 @@ import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" ) -type SDKAction struct { +type SdkAction struct { actionutils.ParentAction } -func (this *SDKAction) Init() { +func (this *SdkAction) Init() { this.Nav("httpdns", "app", "sdk") } -func (this *SDKAction) RunGet(params struct { +func (this *SdkAction) RunGet(params struct { AppId int64 }) { httpdnsutils.AddLeftMenu(this.Parent()) - app := pickApp(params.AppId) - // 构建顶部 tabbar + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } + httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), params.AppId, "sdk") - this.Data["app"] = app this.Show() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_doc.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_doc.go new file mode 100644 index 0000000..f0f4112 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_doc.go @@ -0,0 +1,54 @@ +package apps + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "os" + "path/filepath" + "strings" +) + +type SdkDocAction struct { + actionutils.ParentAction +} + +func (this *SdkDocAction) Init() { + this.Nav("", "", "") +} + +func (this *SdkDocAction) RunGet(params struct { + Platform string +}) { + platform, _, readmeRelativePath, _, err := resolveSDKPlatform(params.Platform) + if err != nil { + this.Fail(err.Error()) + return + } + + var data []byte + uploadedDocPath := findUploadedSDKDocPath(platform) + if len(uploadedDocPath) > 0 { + data, err = os.ReadFile(uploadedDocPath) + } + + sdkRoot, sdkRootErr := findSDKRoot() + if len(data) == 0 && sdkRootErr == nil { + readmePath := filepath.Join(sdkRoot, readmeRelativePath) + data, err = os.ReadFile(readmePath) + } + + if len(data) == 0 { + localDocPath := findLocalSDKDocPath(platform) + if len(localDocPath) > 0 { + data, err = os.ReadFile(localDocPath) + } + } + + if len(data) == 0 || err != nil { + this.Fail("当前服务器未找到 SDK 集成文档,请先在“SDK 集成”页面上传对应平台文档") + return + } + + this.AddHeader("Content-Type", "text/markdown; charset=utf-8") + this.AddHeader("Content-Disposition", "attachment; filename=\"httpdns-sdk-"+strings.ToLower(platform)+"-README.md\";") + _, _ = this.ResponseWriter.Write(data) +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_download.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_download.go new file mode 100644 index 0000000..8427521 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_download.go @@ -0,0 +1,45 @@ +package apps + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "io" + "os" +) + +type SdkDownloadAction struct { + actionutils.ParentAction +} + +func (this *SdkDownloadAction) Init() { + this.Nav("", "", "") +} + +func (this *SdkDownloadAction) RunGet(params struct { + Platform string +}) { + _, _, _, filename, err := resolveSDKPlatform(params.Platform) + if err != nil { + this.Fail(err.Error()) + return + } + + archivePath := findSDKArchivePath(filename) + if len(archivePath) == 0 { + this.Fail("当前服务器未找到 SDK 包,请先在“SDK 集成”页面上传对应平台包: " + filename) + return + } + + fp, err := os.Open(archivePath) + if err != nil { + this.Fail("打开 SDK 包失败: " + err.Error()) + return + } + defer func() { + _ = fp.Close() + }() + + this.AddHeader("Content-Type", "application/zip") + this.AddHeader("Content-Disposition", "attachment; filename=\""+filename+"\";") + this.AddHeader("X-Accel-Buffering", "no") + _, _ = io.Copy(this.ResponseWriter, fp) +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_helpers.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_helpers.go new file mode 100644 index 0000000..42d75e5 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_helpers.go @@ -0,0 +1,149 @@ +package apps + +import ( + "errors" + "github.com/iwind/TeaGo/Tea" + "os" + "path/filepath" + "sort" + "strings" + "time" +) + +func sdkUploadDir() string { + return filepath.Clean(Tea.Root + "/data/httpdns/sdk") +} + +func findFirstExistingDir(paths []string) string { + for _, path := range paths { + stat, err := os.Stat(path) + if err == nil && stat.IsDir() { + return path + } + } + return "" +} + +func findFirstExistingFile(paths []string) string { + for _, path := range paths { + stat, err := os.Stat(path) + if err == nil && !stat.IsDir() { + return path + } + } + return "" +} + +func findNewestExistingFile(paths []string) string { + type fileInfo struct { + path string + modTime time.Time + } + result := fileInfo{} + for _, path := range paths { + stat, err := os.Stat(path) + if err != nil || stat.IsDir() { + continue + } + if len(result.path) == 0 || stat.ModTime().After(result.modTime) || (stat.ModTime().Equal(result.modTime) && path > result.path) { + result.path = path + result.modTime = stat.ModTime() + } + } + return result.path +} + +func findSDKRoot() (string, error) { + candidates := []string{ + filepath.Clean(Tea.Root + "/EdgeHttpDNS/sdk"), + filepath.Clean(Tea.Root + "/edge-httpdns/sdk"), + filepath.Clean(Tea.Root + "/edge-httpdns/edge-httpdns/sdk"), + filepath.Clean(Tea.Root + "/../EdgeHttpDNS/sdk"), + filepath.Clean(Tea.Root + "/../../EdgeHttpDNS/sdk"), + filepath.Clean(Tea.Root + "/../edge-httpdns/sdk"), + filepath.Clean(Tea.Root + "/../../edge-httpdns/sdk"), + } + + dir := findFirstExistingDir(candidates) + if len(dir) > 0 { + return dir, nil + } + + return "", errors.New("SDK files are not found on current server") +} + +func resolveSDKPlatform(platform string) (key string, relativeDir string, readmeRelativePath string, downloadFilename string, err error) { + switch strings.ToLower(strings.TrimSpace(platform)) { + case "android": + return "android", "android", "android/README.md", "httpdns-sdk-android.zip", nil + case "ios": + return "ios", "ios", "ios/README.md", "httpdns-sdk-ios.zip", nil + case "flutter": + return "flutter", "flutter/aliyun_httpdns", "flutter/aliyun_httpdns/README.md", "httpdns-sdk-flutter.zip", nil + default: + return "", "", "", "", errors.New("invalid platform, expected one of: android, ios, flutter") + } +} + +func findSDKArchivePath(downloadFilename string) string { + searchDirs := []string{sdkUploadDir()} + + // 1) Exact filename first. + exactFiles := []string{} + for _, dir := range searchDirs { + exactFiles = append(exactFiles, filepath.Join(dir, downloadFilename)) + } + path := findFirstExistingFile(exactFiles) + if len(path) > 0 { + return path + } + + // 2) Version-suffixed archives, e.g. httpdns-sdk-android-v1.4.8.zip + base := strings.TrimSuffix(downloadFilename, ".zip") + patternName := base + "-*.zip" + matches := []string{} + for _, dir := range searchDirs { + found, _ := filepath.Glob(filepath.Join(dir, patternName)) + for _, file := range found { + stat, err := os.Stat(file) + if err == nil && !stat.IsDir() { + matches = append(matches, file) + } + } + } + if len(matches) > 0 { + return findNewestExistingFile(matches) + } + + return "" +} + +func findUploadedSDKDocPath(platform string) string { + platform = strings.ToLower(strings.TrimSpace(platform)) + if len(platform) == 0 { + return "" + } + + searchDir := sdkUploadDir() + exact := filepath.Join(searchDir, "httpdns-sdk-"+platform+".md") + if file := findFirstExistingFile([]string{exact}); len(file) > 0 { + return file + } + + pattern := filepath.Join(searchDir, "httpdns-sdk-"+platform+"-*.md") + matches, _ := filepath.Glob(pattern) + if len(matches) == 0 { + return "" + } + sort.Strings(matches) + return findNewestExistingFile(matches) +} + +func findLocalSDKDocPath(platform string) string { + filename := strings.ToLower(strings.TrimSpace(platform)) + ".md" + candidates := []string{ + filepath.Clean(Tea.Root + "/edge-admin/web/views/@default/httpdns/apps/docs/" + filename), + filepath.Clean(Tea.Root + "/EdgeAdmin/web/views/@default/httpdns/apps/docs/" + filename), + } + return findFirstExistingFile(candidates) +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_upload.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_upload.go new file mode 100644 index 0000000..f7c5d13 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_upload.go @@ -0,0 +1,264 @@ +package apps + +import ( + "errors" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" + "github.com/iwind/TeaGo/actions" + "os" + "path/filepath" + "sort" + "strconv" + "strings" + "time" +) + +type SdkUploadAction struct { + actionutils.ParentAction +} + +func (this *SdkUploadAction) Init() { + this.Nav("httpdns", "app", "sdk") +} + +func (this *SdkUploadAction) RunGet(params struct { + AppId int64 +}) { + httpdnsutils.AddLeftMenu(this.Parent()) + + app, err := findAppMap(this.Parent(), params.AppId) + if err != nil { + this.ErrorPage(err) + return + } + + httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), params.AppId, "sdk") + + this.Data["app"] = app + this.Data["defaultVersion"] = "1.0.0" + this.Data["uploadedFiles"] = listUploadedSDKFiles() + this.Show() +} + +func (this *SdkUploadAction) RunPost(params struct { + AppId int64 + Platform string + Version string + SDKFile *actions.File + DocFile *actions.File + + Must *actions.Must +}) { + params.Must.Field("appId", params.AppId).Gt(0, "请选择应用") + + platform, _, _, downloadFilename, err := resolveSDKPlatform(params.Platform) + if err != nil { + this.Fail(err.Error()) + return + } + + version, err := normalizeSDKVersion(params.Version) + if err != nil { + this.Fail(err.Error()) + return + } + + if params.SDKFile == nil && params.DocFile == nil { + this.Fail("请至少上传一个文件") + return + } + + uploadDir := sdkUploadDir() + err = os.MkdirAll(uploadDir, 0755) + if err != nil { + this.Fail("创建上传目录失败: " + err.Error()) + return + } + + if params.SDKFile != nil { + filename := strings.ToLower(strings.TrimSpace(params.SDKFile.Filename)) + if !strings.HasSuffix(filename, ".zip") { + this.Fail("SDK 包仅支持 .zip 文件") + return + } + + sdkData, readErr := params.SDKFile.Read() + if readErr != nil { + this.Fail("读取 SDK 包失败: " + readErr.Error()) + return + } + + baseName := strings.TrimSuffix(downloadFilename, ".zip") + err = saveSDKUploadFile(uploadDir, downloadFilename, sdkData) + if err == nil { + err = saveSDKUploadFile(uploadDir, baseName+"-v"+version+".zip", sdkData) + } + if err != nil { + this.Fail("保存 SDK 包失败: " + err.Error()) + return + } + } + + if params.DocFile != nil { + docName := strings.ToLower(strings.TrimSpace(params.DocFile.Filename)) + if !strings.HasSuffix(docName, ".md") { + this.Fail("集成文档仅支持 .md 文件") + return + } + + docData, readErr := params.DocFile.Read() + if readErr != nil { + this.Fail("读取集成文档失败: " + readErr.Error()) + return + } + + filename := "httpdns-sdk-" + platform + ".md" + err = saveSDKUploadFile(uploadDir, filename, docData) + if err == nil { + err = saveSDKUploadFile(uploadDir, "httpdns-sdk-"+platform+"-v"+version+".md", docData) + } + if err != nil { + this.Fail("保存集成文档失败: " + err.Error()) + return + } + } + + this.Success() +} + +func normalizeSDKVersion(version string) (string, error) { + version = strings.TrimSpace(version) + if len(version) == 0 { + version = "1.0.0" + } + for _, c := range version { + if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '_' || c == '-' { + continue + } + return "", errors.New("版本号格式不正确") + } + return version, nil +} + +func saveSDKUploadFile(baseDir string, filename string, data []byte) error { + targetPath := filepath.Join(baseDir, filename) + tmpPath := targetPath + ".tmp" + err := os.WriteFile(tmpPath, data, 0644) + if err != nil { + return err + } + return os.Rename(tmpPath, targetPath) +} + +func listUploadedSDKFiles() []map[string]interface{} { + dir := sdkUploadDir() + entries, err := os.ReadDir(dir) + if err != nil { + return []map[string]interface{}{} + } + + type item struct { + Name string + Platform string + FileType string + Version string + SizeBytes int64 + UpdatedAt int64 + } + + items := make([]item, 0) + for _, entry := range entries { + if entry.IsDir() { + continue + } + name := entry.Name() + platform, version, fileType, ok := parseSDKUploadFilename(name) + if !ok { + continue + } + + info, statErr := entry.Info() + if statErr != nil { + continue + } + + items = append(items, item{ + Name: name, + Platform: platform, + FileType: fileType, + Version: version, + SizeBytes: info.Size(), + UpdatedAt: info.ModTime().Unix(), + }) + } + + sort.Slice(items, func(i, j int) bool { + if items[i].UpdatedAt == items[j].UpdatedAt { + return items[i].Name > items[j].Name + } + return items[i].UpdatedAt > items[j].UpdatedAt + }) + + result := make([]map[string]interface{}, 0, len(items)) + for _, item := range items { + result = append(result, map[string]interface{}{ + "name": item.Name, + "platform": item.Platform, + "fileType": item.FileType, + "version": item.Version, + "sizeText": formatSDKFileSize(item.SizeBytes), + "updatedAt": time.Unix(item.UpdatedAt, 0).Format("2006-01-02 15:04:05"), + }) + } + return result +} + +func parseSDKUploadFilename(filename string) (platform string, version string, fileType string, ok bool) { + if !strings.HasPrefix(filename, "httpdns-sdk-") { + return "", "", "", false + } + + ext := "" + switch { + case strings.HasSuffix(filename, ".zip"): + ext = ".zip" + fileType = "SDK包" + case strings.HasSuffix(filename, ".md"): + ext = ".md" + fileType = "集成文档" + default: + return "", "", "", false + } + + main := strings.TrimSuffix(strings.TrimPrefix(filename, "httpdns-sdk-"), ext) + version = "latest" + if idx := strings.Index(main, "-v"); idx > 0 && idx+2 < len(main) { + version = main[idx+2:] + main = main[:idx] + } + + main = strings.ToLower(strings.TrimSpace(main)) + switch main { + case "android", "ios", "flutter": + platform = main + return platform, version, fileType, true + default: + return "", "", "", false + } +} + +func formatSDKFileSize(size int64) string { + if size < 1024 { + return strconv.FormatInt(size, 10) + " B" + } + sizeKB := float64(size) / 1024 + if sizeKB < 1024 { + return strconv.FormatFloat(sizeKB, 'f', 1, 64) + " KB" + } + sizeMB := sizeKB / 1024 + if sizeMB < 1024 { + return strconv.FormatFloat(sizeMB, 'f', 1, 64) + " MB" + } + sizeGB := sizeMB / 1024 + return strconv.FormatFloat(sizeGB, 'f', 1, 64) + " GB" +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_upload_delete.go b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_upload_delete.go new file mode 100644 index 0000000..5a6b906 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/apps/sdk_upload_delete.go @@ -0,0 +1,57 @@ +package apps + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "os" + "path/filepath" + "strings" +) + +type SdkUploadDeleteAction struct { + actionutils.ParentAction +} + +func (this *SdkUploadDeleteAction) Init() { + this.Nav("httpdns", "app", "sdk") +} + +func (this *SdkUploadDeleteAction) RunPost(params struct { + AppId int64 + Filename string +}) { + if params.AppId <= 0 { + this.Fail("请选择应用") + return + } + + filename := strings.TrimSpace(params.Filename) + if len(filename) == 0 { + this.Fail("文件名不能为空") + return + } + if strings.Contains(filename, "/") || strings.Contains(filename, "\\") || strings.Contains(filename, "..") { + this.Fail("文件名不合法") + return + } + if !strings.HasPrefix(filename, "httpdns-sdk-") { + this.Fail("不允许删除该文件") + return + } + if !(strings.HasSuffix(filename, ".zip") || strings.HasSuffix(filename, ".md")) { + this.Fail("不允许删除该文件") + return + } + + fullPath := filepath.Join(sdkUploadDir(), filename) + _, err := os.Stat(fullPath) + if err != nil { + this.Success() + return + } + if err = os.Remove(fullPath); err != nil { + this.Fail("删除失败: " + err.Error()) + return + } + + this.Success() +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/certs.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/certs.go index 645d21a..f0d80ca 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/certs.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/certs.go @@ -2,8 +2,6 @@ package clusters import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/policies" ) type CertsAction struct { @@ -15,7 +13,5 @@ func (this *CertsAction) Init() { } func (this *CertsAction) RunGet(params struct{}) { - httpdnsutils.AddLeftMenu(this.Parent()) - this.Data["certs"] = policies.LoadPublicSNICertificates() - this.Show() + this.RedirectURL("/httpdns/clusters") } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster.go index 94bbb37..03dbd64 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster.go @@ -1,8 +1,11 @@ package clusters import ( + "strings" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" + "github.com/iwind/TeaGo/maps" ) type ClusterAction struct { @@ -20,19 +23,75 @@ func (this *ClusterAction) RunGet(params struct { Keyword string }) { httpdnsutils.AddLeftMenu(this.Parent()) - cluster := pickCluster(params.ClusterId) - // 构建顶部 tabbar + cluster, err := findClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return + } + httpdnsutils.AddClusterTabbar(this.Parent(), cluster.GetString("name"), params.ClusterId, "node") + nodes, err := listNodeMaps(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return + } + nodes = filterClusterNodes(nodes, params.InstalledState, params.ActiveState, params.Keyword) + this.Data["clusterId"] = params.ClusterId this.Data["cluster"] = cluster this.Data["installState"] = params.InstalledState this.Data["activeState"] = params.ActiveState this.Data["keyword"] = params.Keyword - nodes := mockNodes(params.ClusterId, params.InstalledState, params.ActiveState, params.Keyword) this.Data["nodes"] = nodes this.Data["hasNodes"] = len(nodes) > 0 this.Data["page"] = "" this.Show() } + +func filterClusterNodes(nodes []maps.Map, installedState int, activeState int, keyword string) []maps.Map { + keyword = strings.ToLower(strings.TrimSpace(keyword)) + + result := make([]maps.Map, 0, len(nodes)) + for _, node := range nodes { + isInstalled := node.GetBool("isInstalled") + if installedState == 1 && !isInstalled { + continue + } + if installedState == 2 && isInstalled { + continue + } + + status := node.GetMap("status") + isOnline := node.GetBool("isOn") && node.GetBool("isUp") && status.GetBool("isActive") + if activeState == 1 && !isOnline { + continue + } + if activeState == 2 && isOnline { + continue + } + + if len(keyword) > 0 { + hit := strings.Contains(strings.ToLower(node.GetString("name")), keyword) + if !hit { + ipAddresses, ok := node["ipAddresses"].([]maps.Map) + if ok { + for _, ipAddr := range ipAddresses { + if strings.Contains(strings.ToLower(ipAddr.GetString("ip")), keyword) { + hit = true + break + } + } + } + } + if !hit { + continue + } + } + + result = append(result, node) + } + + return result +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/index.go index c516d9e..5e203f5 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/index.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/index.go @@ -1,8 +1,10 @@ package node import ( + "time" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/iwind/TeaGo/maps" + timeutil "github.com/iwind/TeaGo/utils/time" ) type IndexAction struct { @@ -18,51 +20,37 @@ func (this *IndexAction) RunGet(params struct { ClusterId int64 NodeId int64 }) { - this.Data["clusterId"] = params.ClusterId - this.Data["nodeId"] = params.NodeId - this.Data["currentCluster"] = maps.Map{"id": params.ClusterId, "name": "Mock Cluster"} - - this.Data["nodeDatetime"] = "2026-02-22 12:00:00" - this.Data["nodeTimeDiff"] = 0 - this.Data["shouldUpgrade"] = false - this.Data["newVersion"] = "" - - this.Data["node"] = maps.Map{ - "id": params.NodeId, - "name": "Mock HTTPDNS Node", - "ipAddresses": []maps.Map{{"ip": "100.200.100.200", "name": "Public IP", "canAccess": true, "isOn": true, "isUp": true}}, - "cluster": maps.Map{"id": params.ClusterId, "name": "Mock Cluster", "installDir": "/opt/edge-httpdns"}, - "installDir": "/opt/edge-httpdns", - "isInstalled": true, - "uniqueId": "m-1234567890", - "secret": "mock-secret-key", - "isOn": true, - "isUp": true, - "apiNodeAddrs": []string{"192.168.1.100:8001"}, - "login": nil, - - "status": maps.Map{ - "isActive": true, - "updatedAt": 1670000000, - "hostname": "node-01.local", - "cpuUsage": 0.15, - "cpuUsageText": "15.00%", - "memUsage": 0.45, - "memUsageText": "45.00%", - "connectionCount": 100, - "buildVersion": "1.0.0", - "cpuPhysicalCount": 4, - "cpuLogicalCount": 8, - "load1m": "0.50", - "load5m": "0.60", - "load15m": "0.70", - "cacheTotalDiskSize": "10G", - "cacheTotalMemorySize": "2G", - "exePath": "/opt/edge-httpdns/bin/edge-httpdns", - "apiSuccessPercent": 100.0, - "apiAvgCostSeconds": 0.05, - }, + node, err := findHTTPDNSNodeMap(this.Parent(), params.NodeId) + if err != nil { + this.ErrorPage(err) + return + } + cluster, err := findHTTPDNSClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return } + this.Data["clusterId"] = params.ClusterId + this.Data["nodeId"] = params.NodeId + this.Data["node"] = node + this.Data["currentCluster"] = cluster + + status := node.GetMap("status") + updatedAt := status.GetInt64("updatedAt") + nodeDatetime := "" + nodeTimeDiff := int64(0) + if updatedAt > 0 { + nodeDatetime = timeutil.FormatTime("Y-m-d H:i:s", updatedAt) + nodeTimeDiff = time.Now().Unix() - updatedAt + if nodeTimeDiff < 0 { + nodeTimeDiff = -nodeTimeDiff + } + } + this.Data["nodeDatetime"] = nodeDatetime + this.Data["nodeTimeDiff"] = nodeTimeDiff + + this.Data["shouldUpgrade"] = false + this.Data["newVersion"] = "" this.Show() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/install.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/install.go index eeb79a6..c90c86d 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/install.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/install.go @@ -1,8 +1,12 @@ -package node +package node import ( + "encoding/json" + "strings" + "time" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/iwind/TeaGo/maps" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" ) type InstallAction struct { @@ -14,28 +18,87 @@ func (this *InstallAction) Init() { this.SecondMenu("nodes") } -func (this *InstallAction) RunGet(params struct{ ClusterId int64; NodeId int64 }) { +func (this *InstallAction) RunGet(params struct { + ClusterId int64 + NodeId int64 +}) { + node, err := findHTTPDNSNodeMap(this.Parent(), params.NodeId) + if err != nil { + this.ErrorPage(err) + return + } + cluster, err := findHTTPDNSClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["clusterId"] = params.ClusterId this.Data["nodeId"] = params.NodeId - this.Data["currentCluster"] = maps.Map{"id": params.ClusterId, "name": "Mock Cluster"} + this.Data["currentCluster"] = cluster + this.Data["node"] = node + this.Data["installStatus"] = node.GetMap("installStatus") - this.Data["apiEndpoints"] = "\"http://127.0.0.1:7788\"" - this.Data["sshAddr"] = "192.168.1.100:22" - - this.Data["node"] = maps.Map{ - "id": params.NodeId, - "name": "Mock Node", - "isInstalled": false, - "uniqueId": "m-1234567890", - "secret": "mock-secret-key", - "installDir": "/opt/edge-httpdns", - "cluster": maps.Map{"installDir": "/opt/edge-httpdns"}, + apiNodesResp, err := this.RPC().APINodeRPC().FindAllEnabledAPINodes(this.AdminContext(), &pb.FindAllEnabledAPINodesRequest{}) + if err != nil { + this.ErrorPage(err) + return } - this.Data["installStatus"] = nil - + apiEndpoints := make([]string, 0, 8) + for _, apiNode := range apiNodesResp.GetApiNodes() { + if !apiNode.GetIsOn() { + continue + } + apiEndpoints = append(apiEndpoints, apiNode.GetAccessAddrs()...) + } + if len(apiEndpoints) == 0 { + apiEndpoints = []string{"http://127.0.0.1:7788"} + } + this.Data["apiEndpoints"] = "\"" + strings.Join(apiEndpoints, "\", \"") + "\"" + this.Data["sshAddr"] = "" this.Show() } -func (this *InstallAction) RunPost(params struct{ NodeId int64 }) { +func (this *InstallAction) RunPost(params struct { + NodeId int64 +}) { + nodeResp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err != nil { + this.ErrorPage(err) + return + } + node := nodeResp.GetNode() + if node == nil { + this.Fail("节点不存在") + return + } + + existingStatus := map[string]interface{}{} + if len(node.GetInstallStatusJSON()) > 0 { + _ = json.Unmarshal(node.GetInstallStatusJSON(), &existingStatus) + } + + existingStatus["isRunning"] = true + existingStatus["isFinished"] = false + existingStatus["isOk"] = false + existingStatus["error"] = "" + existingStatus["errorCode"] = "" + existingStatus["updatedAt"] = time.Now().Unix() + + installStatusJSON, _ := json.Marshal(existingStatus) + _, err = this.RPC().HTTPDNSNodeRPC().UpdateHTTPDNSNodeStatus(this.AdminContext(), &pb.UpdateHTTPDNSNodeStatusRequest{ + NodeId: params.NodeId, + IsUp: node.GetIsUp(), + IsInstalled: false, + IsActive: node.GetIsActive(), + StatusJSON: node.GetStatusJSON(), + InstallStatusJSON: installStatusJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/logs.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/logs.go index e88e779..35e4168 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/logs.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/logs.go @@ -1,7 +1,11 @@ -package node +package node import ( + "strings" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + timeutil "github.com/iwind/TeaGo/utils/time" "github.com/iwind/TeaGo/maps" ) @@ -14,18 +18,65 @@ func (this *LogsAction) Init() { this.SecondMenu("nodes") } -func (this *LogsAction) RunGet(params struct{ ClusterId int64; NodeId int64 }) { +func (this *LogsAction) RunGet(params struct { + ClusterId int64 + NodeId int64 + DayFrom string + DayTo string + Level string + Keyword string +}) { + node, err := findHTTPDNSNodeMap(this.Parent(), params.NodeId) + if err != nil { + this.ErrorPage(err) + return + } + cluster, err := findHTTPDNSClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["clusterId"] = params.ClusterId this.Data["nodeId"] = params.NodeId - this.Data["currentCluster"] = maps.Map{"id": params.ClusterId, "name": "Mock Cluster"} + this.Data["currentCluster"] = cluster + this.Data["node"] = node + this.Data["dayFrom"] = params.DayFrom + this.Data["dayTo"] = params.DayTo + this.Data["level"] = params.Level + this.Data["keyword"] = params.Keyword - this.Data["dayFrom"] = "" - this.Data["dayTo"] = "" - this.Data["keyword"] = "" - this.Data["level"] = "" - this.Data["logs"] = []maps.Map{} + day := strings.TrimSpace(params.DayFrom) + if len(day) == 0 { + day = strings.TrimSpace(params.DayTo) + } + + resp, err := this.RPC().HTTPDNSRuntimeLogRPC().ListHTTPDNSRuntimeLogs(this.AdminContext(), &pb.ListHTTPDNSRuntimeLogsRequest{ + Day: day, + ClusterId: params.ClusterId, + NodeId: params.NodeId, + Level: strings.TrimSpace(params.Level), + Keyword: strings.TrimSpace(params.Keyword), + Offset: 0, + Size: 100, + }) + if err != nil { + this.ErrorPage(err) + return + } + + logs := make([]maps.Map, 0, len(resp.GetLogs())) + for _, item := range resp.GetLogs() { + logs = append(logs, maps.Map{ + "level": item.GetLevel(), + "tag": item.GetType(), + "description": item.GetDescription(), + "createdAt": item.GetCreatedAt(), + "createdTime": timeutil.FormatTime("Y-m-d H:i:s", item.GetCreatedAt()), + "count": item.GetCount(), + }) + } + this.Data["logs"] = logs this.Data["page"] = "" - this.Data["node"] = maps.Map{"id": params.NodeId, "name": "Mock Node"} - this.Show() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/rpc_helpers.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/rpc_helpers.go new file mode 100644 index 0000000..d4764e4 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/rpc_helpers.go @@ -0,0 +1,183 @@ +package node + +import ( + "encoding/json" + "fmt" + "strings" + + "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/maps" +) + +func findHTTPDNSClusterMap(parent *actionutils.ParentAction, clusterID int64) (maps.Map, error) { + resp, err := parent.RPC().HTTPDNSClusterRPC().FindHTTPDNSCluster(parent.AdminContext(), &pb.FindHTTPDNSClusterRequest{ + ClusterId: clusterID, + }) + if err != nil { + return nil, err + } + if resp.GetCluster() == nil { + return maps.Map{ + "id": clusterID, + "name": "", + "installDir": "/opt/edge-httpdns", + }, nil + } + + cluster := resp.GetCluster() + installDir := strings.TrimSpace(cluster.GetInstallDir()) + if len(installDir) == 0 { + installDir = "/opt/edge-httpdns" + } + return maps.Map{ + "id": cluster.GetId(), + "name": cluster.GetName(), + "installDir": installDir, + }, nil +} + +func findHTTPDNSNodeMap(parent *actionutils.ParentAction, nodeID int64) (maps.Map, error) { + resp, err := parent.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(parent.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: nodeID, + }) + if err != nil { + return nil, err + } + if resp.GetNode() == nil { + return maps.Map{}, nil + } + + node := resp.GetNode() + statusMap := decodeNodeStatus(node.GetStatusJSON()) + installStatusMap := decodeInstallStatus(node.GetInstallStatusJSON()) + + var ipAddresses = []maps.Map{} + if installStatusMap.Has("ipAddresses") { + for _, addr := range installStatusMap.GetSlice("ipAddresses") { + if addrMap, ok := addr.(map[string]interface{}); ok { + ipAddresses = append(ipAddresses, maps.Map(addrMap)) + } + } + } else { + ip := node.GetName() + if savedIP := strings.TrimSpace(installStatusMap.GetString("ipAddr")); len(savedIP) > 0 { + ip = savedIP + } else if hostIP := strings.TrimSpace(statusMap.GetString("hostIP")); len(hostIP) > 0 { + ip = hostIP + } + ipAddresses = append(ipAddresses, maps.Map{ + "id": node.GetId(), + "name": "Public IP", + "ip": ip, + "canAccess": true, + "isOn": node.GetIsOn(), + "isUp": node.GetIsUp(), + }) + } + + installDir := strings.TrimSpace(node.GetInstallDir()) + if len(installDir) == 0 { + installDir = "/opt/edge-httpdns" + } + + clusterMap, err := findHTTPDNSClusterMap(parent, node.GetClusterId()) + if err != nil { + return nil, err + } + + // 构造 node.login 用于 index.html 展示 SSH 信息 + var loginMap maps.Map = nil + sshInfo := installStatusMap.GetMap("ssh") + if sshInfo != nil { + grantId := sshInfo.GetInt64("grantId") + var grantMap maps.Map = nil + if grantId > 0 { + grantResp, grantErr := parent.RPC().NodeGrantRPC().FindEnabledNodeGrant(parent.AdminContext(), &pb.FindEnabledNodeGrantRequest{ + NodeGrantId: grantId, + }) + if grantErr == nil && grantResp.GetNodeGrant() != nil { + g := grantResp.GetNodeGrant() + grantMap = maps.Map{ + "id": g.Id, + "name": g.Name, + "methodName": g.Method, + "username": g.Username, + } + } + } + + loginMap = maps.Map{ + "params": maps.Map{ + "host": sshInfo.GetString("host"), + "port": sshInfo.GetInt("port"), + }, + "grant": grantMap, + } + } + + return maps.Map{ + "id": node.GetId(), + "clusterId": node.GetClusterId(), + "name": node.GetName(), + "isOn": node.GetIsOn(), + "isUp": node.GetIsUp(), + "isInstalled": node.GetIsInstalled(), + "isActive": node.GetIsActive(), + "uniqueId": node.GetUniqueId(), + "secret": node.GetSecret(), + "installDir": installDir, + "status": statusMap, + "installStatus": installStatusMap, + "cluster": clusterMap, + "login": loginMap, + "apiNodeAddrs": []string{}, + "ipAddresses": ipAddresses, + }, nil +} + +func decodeNodeStatus(raw []byte) maps.Map { + status := &nodeconfigs.NodeStatus{} + if len(raw) > 0 { + _ = json.Unmarshal(raw, status) + } + cpuText := fmt.Sprintf("%.2f%%", status.CPUUsage*100) + memText := fmt.Sprintf("%.2f%%", status.MemoryUsage*100) + + return maps.Map{ + "isActive": status.IsActive, + "updatedAt": status.UpdatedAt, + "hostname": status.Hostname, + "hostIP": status.HostIP, + "cpuUsage": status.CPUUsage, + "cpuUsageText": cpuText, + "memUsage": status.MemoryUsage, + "memUsageText": memText, + "load1m": status.Load1m, + "load5m": status.Load5m, + "load15m": status.Load15m, + "buildVersion": status.BuildVersion, + "cpuPhysicalCount": status.CPUPhysicalCount, + "cpuLogicalCount": status.CPULogicalCount, + "exePath": status.ExePath, + "apiSuccessPercent": status.APISuccessPercent, + "apiAvgCostSeconds": status.APIAvgCostSeconds, + } +} + +func decodeInstallStatus(raw []byte) maps.Map { + result := maps.Map{ + "isRunning": false, + "isFinished": true, + "isOk": true, + "error": "", + "errorCode": "", + } + if len(raw) == 0 { + return result + } + + _ = json.Unmarshal(raw, &result) + return result +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/start.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/start.go index de506c5..55fa5c8 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/start.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/start.go @@ -1,13 +1,41 @@ -package node +package node import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" ) type StartAction struct { actionutils.ParentAction } -func (this *StartAction) RunPost(params struct{ NodeId int64 }) { +func (this *StartAction) RunPost(params struct { + NodeId int64 +}) { + resp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err != nil { + this.ErrorPage(err) + return + } + node := resp.GetNode() + if node == nil { + this.Fail("节点不存在") + return + } + + _, err = this.RPC().HTTPDNSNodeRPC().UpdateHTTPDNSNodeStatus(this.AdminContext(), &pb.UpdateHTTPDNSNodeStatusRequest{ + NodeId: params.NodeId, + IsUp: true, + IsInstalled: node.GetIsInstalled(), + IsActive: true, + StatusJSON: node.GetStatusJSON(), + InstallStatusJSON: node.GetInstallStatusJSON(), + }) + if err != nil { + this.ErrorPage(err) + return + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/status.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/status.go index a85d567..cc48d5c 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/status.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/status.go @@ -2,7 +2,7 @@ package node import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/iwind/TeaGo/maps" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" ) type StatusAction struct { @@ -14,14 +14,28 @@ func (this *StatusAction) Init() { this.SecondMenu("nodes") } -func (this *StatusAction) RunPost(params struct{ NodeId int64 }) { - this.Data["installStatus"] = maps.Map{ - "isRunning": false, - "isFinished": true, - "isOk": true, - "error": "", - "errorCode": "", +func (this *StatusAction) RunPost(params struct { + NodeId int64 +}) { + resp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err != nil { + this.ErrorPage(err) + return } - this.Data["isInstalled"] = true + if resp.GetNode() == nil { + this.Fail("节点不存在") + return + } + + nodeMap, err := findHTTPDNSNodeMap(this.Parent(), params.NodeId) + if err != nil { + this.ErrorPage(err) + return + } + + this.Data["installStatus"] = nodeMap.GetMap("installStatus") + this.Data["isInstalled"] = nodeMap.GetBool("isInstalled") this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/stop.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/stop.go index 10b3ad3..3865b20 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/stop.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/stop.go @@ -1,13 +1,41 @@ -package node +package node import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" ) type StopAction struct { actionutils.ParentAction } -func (this *StopAction) RunPost(params struct{ NodeId int64 }) { +func (this *StopAction) RunPost(params struct { + NodeId int64 +}) { + resp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err != nil { + this.ErrorPage(err) + return + } + node := resp.GetNode() + if node == nil { + this.Fail("节点不存在") + return + } + + _, err = this.RPC().HTTPDNSNodeRPC().UpdateHTTPDNSNodeStatus(this.AdminContext(), &pb.UpdateHTTPDNSNodeStatusRequest{ + NodeId: params.NodeId, + IsUp: node.GetIsUp(), + IsInstalled: node.GetIsInstalled(), + IsActive: false, + StatusJSON: node.GetStatusJSON(), + InstallStatusJSON: node.GetInstallStatusJSON(), + }) + if err != nil { + this.ErrorPage(err) + return + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/update.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/update.go index 1e86260..3459d5f 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/update.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/update.go @@ -1,7 +1,14 @@ -package node +package node import ( + "encoding/json" + "net" + "regexp" + "strings" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/maps" ) @@ -14,28 +21,210 @@ func (this *UpdateAction) Init() { this.SecondMenu("nodes") } -func (this *UpdateAction) RunGet(params struct{ ClusterId int64; NodeId int64 }) { +func (this *UpdateAction) RunGet(params struct { + ClusterId int64 + NodeId int64 +}) { + node, err := findHTTPDNSNodeMap(this.Parent(), params.NodeId) + if err != nil { + this.ErrorPage(err) + return + } + cluster, err := findHTTPDNSClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["clusterId"] = params.ClusterId this.Data["nodeId"] = params.NodeId - this.Data["currentCluster"] = maps.Map{"id": params.ClusterId, "name": "Mock Cluster"} - - this.Data["clusters"] = []maps.Map{{"id": params.ClusterId, "name": "Mock Cluster"}} - this.Data["loginId"] = 0 - this.Data["sshHost"] = "192.168.1.100" - this.Data["sshPort"] = 22 - this.Data["grant"] = nil + this.Data["currentCluster"] = cluster + this.Data["clusters"] = []maps.Map{cluster} this.Data["apiNodeAddrs"] = []string{} + this.Data["node"] = node - this.Data["node"] = maps.Map{ - "id": params.NodeId, - "name": "Mock Node", - "isOn": true, - "ipAddresses": []maps.Map{}, + sshHost := "" + sshPort := 22 + ipAddresses := []maps.Map{} + var grantId int64 + this.Data["grant"] = nil + + resp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err == nil && resp.GetNode() != nil { + if len(resp.GetNode().GetInstallStatusJSON()) > 0 { + installStatus := maps.Map{} + _ = json.Unmarshal(resp.GetNode().GetInstallStatusJSON(), &installStatus) + sshInfo := installStatus.GetMap("ssh") + if sshInfo != nil { + if h := strings.TrimSpace(sshInfo.GetString("host")); len(h) > 0 { + sshHost = h + } + if p := sshInfo.GetInt("port"); p > 0 { + sshPort = p + } + grantId = sshInfo.GetInt64("grantId") + } + + if installStatus.Has("ipAddresses") { + for _, addr := range installStatus.GetSlice("ipAddresses") { + if addrMap, ok := addr.(map[string]interface{}); ok { + ipAddresses = append(ipAddresses, maps.Map(addrMap)) + } + } + } else if ip := strings.TrimSpace(installStatus.GetString("ipAddr")); len(ip) > 0 { + ipAddresses = append(ipAddresses, maps.Map{ + "ip": ip, + "name": "", + "canAccess": true, + "isOn": true, + "isUp": true, + }) + } + } + } + + this.Data["sshHost"] = sshHost + this.Data["sshPort"] = sshPort + this.Data["ipAddresses"] = ipAddresses + + if grantId > 0 { + grantResp, grantErr := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{ + NodeGrantId: grantId, + }) + if grantErr == nil && grantResp.GetNodeGrant() != nil { + g := grantResp.GetNodeGrant() + this.Data["grant"] = maps.Map{ + "id": g.Id, + "name": g.Name, + "methodName": g.Method, + } + } } this.Show() } -func (this *UpdateAction) RunPost(params struct{ NodeId int64 }) { +func (this *UpdateAction) RunPost(params struct { + NodeId int64 + Name string + ClusterId int64 + IsOn bool + SshHost string + SshPort int + GrantId int64 + IpAddressesJSON []byte + + Must *actions.Must +}) { + params.Name = strings.TrimSpace(params.Name) + params.Must.Field("name", params.Name).Require("请输入节点名称") + + params.SshHost = strings.TrimSpace(params.SshHost) + hasSSHUpdate := len(params.SshHost) > 0 || params.SshPort > 0 || params.GrantId > 0 + if hasSSHUpdate { + if len(params.SshHost) == 0 { + this.Fail("请输入 SSH 主机地址") + } + if params.SshPort <= 0 || params.SshPort > 65535 { + this.Fail("SSH 端口范围必须在 1-65535 之间") + } + if params.GrantId <= 0 { + this.Fail("请选择 SSH 登录认证") + } + + if regexp.MustCompile(`^\d+\.\d+\.\d+\.\d+$`).MatchString(params.SshHost) && net.ParseIP(params.SshHost) == nil { + this.Fail("SSH 主机地址格式错误") + } + } + + ipAddresses := []maps.Map{} + if len(params.IpAddressesJSON) > 0 { + err := json.Unmarshal(params.IpAddressesJSON, &ipAddresses) + if err != nil { + this.ErrorPage(err) + return + } + } + + for _, addr := range ipAddresses { + ip := addr.GetString("ip") + if net.ParseIP(ip) == nil { + this.Fail("IP地址格式错误: " + ip) + } + } + + needUpdateInstallStatus := hasSSHUpdate || len(ipAddresses) > 0 + + resp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err != nil { + this.ErrorPage(err) + return + } + if resp.GetNode() == nil { + this.Fail("节点不存在") + return + } + node := resp.GetNode() + + installDir := strings.TrimSpace(node.GetInstallDir()) + if len(installDir) == 0 { + installDir = "/opt/edge-httpdns" + } + + _, err = this.RPC().HTTPDNSNodeRPC().UpdateHTTPDNSNode(this.AdminContext(), &pb.UpdateHTTPDNSNodeRequest{ + NodeId: params.NodeId, + Name: params.Name, + InstallDir: installDir, + IsOn: params.IsOn, + }) + if err != nil { + this.ErrorPage(err) + return + } + + if needUpdateInstallStatus { + installStatus := maps.Map{ + "isRunning": false, + "isFinished": true, + "isOk": node.GetIsInstalled(), + "error": "", + "errorCode": "", + } + if len(node.GetInstallStatusJSON()) > 0 { + _ = json.Unmarshal(node.GetInstallStatusJSON(), &installStatus) + } + if hasSSHUpdate { + installStatus["ssh"] = maps.Map{ + "host": params.SshHost, + "port": params.SshPort, + "grantId": params.GrantId, + } + } + if len(ipAddresses) > 0 { + installStatus["ipAddresses"] = ipAddresses + } else { + delete(installStatus, "ipAddresses") + delete(installStatus, "ipAddr") // Cleanup legacy + } + + installStatusJSON, _ := json.Marshal(installStatus) + _, err = this.RPC().HTTPDNSNodeRPC().UpdateHTTPDNSNodeStatus(this.AdminContext(), &pb.UpdateHTTPDNSNodeStatusRequest{ + NodeId: params.NodeId, + IsUp: node.GetIsUp(), + IsInstalled: node.GetIsInstalled(), + IsActive: node.GetIsActive(), + StatusJSON: node.GetStatusJSON(), + InstallStatusJSON: installStatusJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + } + this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/updateInstallStatus.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/updateInstallStatus.go index f655c57..e713a97 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/updateInstallStatus.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/cluster/node/updateInstallStatus.go @@ -1,13 +1,58 @@ -package node +package node import ( + "encoding/json" + "time" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" ) type UpdateInstallStatusAction struct { actionutils.ParentAction } -func (this *UpdateInstallStatusAction) RunPost(params struct{ NodeId int64 }) { +func (this *UpdateInstallStatusAction) RunPost(params struct { + NodeId int64 + IsInstalled bool +}) { + resp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err != nil { + this.ErrorPage(err) + return + } + node := resp.GetNode() + if node == nil { + this.Fail("节点不存在") + return + } + + installStatus := map[string]interface{}{} + if len(node.GetInstallStatusJSON()) > 0 { + _ = json.Unmarshal(node.GetInstallStatusJSON(), &installStatus) + } + installStatus["isRunning"] = false + installStatus["isFinished"] = true + installStatus["isOk"] = params.IsInstalled + installStatus["error"] = "" + installStatus["errorCode"] = "" + installStatus["updatedAt"] = time.Now().Unix() + + installStatusJSON, _ := json.Marshal(installStatus) + + _, err = this.RPC().HTTPDNSNodeRPC().UpdateHTTPDNSNodeStatus(this.AdminContext(), &pb.UpdateHTTPDNSNodeStatusRequest{ + NodeId: params.NodeId, + IsUp: node.GetIsUp(), + IsInstalled: params.IsInstalled, + IsActive: node.GetIsActive(), + StatusJSON: node.GetStatusJSON(), + InstallStatusJSON: installStatusJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/clusterSettings.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/clusterSettings.go index 9c87642..624ebd0 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/clusterSettings.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/clusterSettings.go @@ -7,7 +7,7 @@ import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/policies" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs" "github.com/iwind/TeaGo/actions" @@ -27,80 +27,79 @@ func (this *ClusterSettingsAction) RunGet(params struct { Section string }) { httpdnsutils.AddLeftMenu(this.Parent()) - cluster := pickCluster(params.ClusterId) - settings := loadClusterSettings(cluster) - cluster["name"] = settings.GetString("name") - // 构建顶部 tabbar + cluster, err := findClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return + } httpdnsutils.AddClusterTabbar(this.Parent(), cluster.GetString("name"), params.ClusterId, "setting") - // 当前选中的 section - section := params.Section + section := strings.TrimSpace(params.Section) if len(section) == 0 { section = "basic" } - this.Data["activeSection"] = section - // 左侧菜单 + settings := maps.Map{ + "name": cluster.GetString("name"), + "gatewayDomain": cluster.GetString("gatewayDomain"), + "cacheTtl": cluster.GetInt("defaultTTL"), + "fallbackTimeout": cluster.GetInt("fallbackTimeout"), + "installDir": cluster.GetString("installDir"), + "isOn": cluster.GetBool("isOn"), + "isDefaultCluster": cluster.GetBool("isDefault"), + } + if settings.GetInt("cacheTtl") <= 0 { + settings["cacheTtl"] = 30 + } + if settings.GetInt("fallbackTimeout") <= 0 { + settings["fallbackTimeout"] = 300 + } + if len(settings.GetString("installDir")) == 0 { + settings["installDir"] = "/opt/edge-httpdns" + } + + listenAddresses := []*serverconfigs.NetworkAddressConfig{ + { + Protocol: serverconfigs.ProtocolHTTPS, + Host: "", + PortRange: "443", + }, + } + sslPolicy := &sslconfigs.SSLPolicy{ + IsOn: true, + MinVersion: "TLS 1.1", + } + + if rawTLS := strings.TrimSpace(cluster.GetString("tlsPolicyJSON")); len(rawTLS) > 0 { + tlsConfig := maps.Map{} + if err := json.Unmarshal([]byte(rawTLS), &tlsConfig); err == nil { + if listenRaw := tlsConfig.Get("listen"); listenRaw != nil { + if data, err := json.Marshal(listenRaw); err == nil { + _ = json.Unmarshal(data, &listenAddresses) + } + } + if sslRaw := tlsConfig.Get("sslPolicy"); sslRaw != nil { + if data, err := json.Marshal(sslRaw); err == nil { + _ = json.Unmarshal(data, sslPolicy) + } + } + } + } + + this.Data["activeSection"] = section cid := strconv.FormatInt(params.ClusterId, 10) this.Data["leftMenuItems"] = []map[string]interface{}{ {"name": "基础设置", "url": "/httpdns/clusters/cluster/settings?clusterId=" + cid + "§ion=basic", "isActive": section == "basic"}, - {"name": "端口设置", "url": "/httpdns/clusters/cluster/settings?clusterId=" + cid + "§ion=tls", "isActive": section == "tls"}, + {"name": "TLS", "url": "/httpdns/clusters/cluster/settings?clusterId=" + cid + "§ion=tls", "isActive": section == "tls"}, } - - settings["isDefaultCluster"] = (policies.LoadDefaultClusterID() == cluster.GetInt64("id")) - this.Data["cluster"] = cluster - // 构造前端需要的 tlsConfig 格式 - var listenAddresses []*serverconfigs.NetworkAddressConfig - listenAddrsRaw := settings.GetString("listenAddrsJSON") - if len(listenAddrsRaw) > 0 { - _ = json.Unmarshal([]byte(listenAddrsRaw), &listenAddresses) - } else { - // 默认 443 端口 - listenAddresses = []*serverconfigs.NetworkAddressConfig{ - { - Protocol: serverconfigs.ProtocolHTTPS, - Host: "", - PortRange: "443", - }, - } - } - - // 构造前端需要的 SSLPolicy - var sslPolicy *sslconfigs.SSLPolicy - originCertPem := settings.GetString("originCertPem") - originKeyPem := settings.GetString("originKeyPem") - if len(originCertPem) > 0 && len(originKeyPem) > 0 { - sslPolicy = &sslconfigs.SSLPolicy{ - IsOn: true, - MinVersion: settings.GetString("tlsMinVersion"), - CipherSuitesIsOn: settings.GetBool("tlsCipherSuitesOn"), - OCSPIsOn: settings.GetBool("tlsOcspOn"), - ClientAuthType: int(settings.GetInt32("tlsClientAuthType")), - Certs: []*sslconfigs.SSLCertConfig{ - { - IsOn: true, - CertData: []byte(originCertPem), - KeyData: []byte(originKeyPem), - }, - }, - } - } else { - sslPolicy = &sslconfigs.SSLPolicy{ - IsOn: true, - MinVersion: "TLS 1.1", - } - } - + this.Data["settings"] = settings this.Data["tlsConfig"] = maps.Map{ "isOn": true, "listen": listenAddresses, "sslPolicy": sslPolicy, } - - this.Data["cluster"] = cluster - this.Data["settings"] = settings this.Show() } @@ -120,88 +119,80 @@ func (this *ClusterSettingsAction) RunPost(params struct { Must *actions.Must CSRF *actionutils.CSRF }) { - params.Must.Field("clusterId", params.ClusterId).Gt(0, "please select cluster") - params.Must.Field("name", params.Name).Require("please input cluster name") - params.Must.Field("gatewayDomain", params.GatewayDomain).Require("please input service domain") - params.Must.Field("cacheTtl", params.CacheTtl).Gt(0, "cache ttl should be greater than 0") - params.Must.Field("fallbackTimeout", params.FallbackTimeout).Gt(0, "fallback timeout should be greater than 0") - params.Must.Field("installDir", params.InstallDir).Require("please input install dir") + params.Name = strings.TrimSpace(params.Name) + params.GatewayDomain = strings.TrimSpace(params.GatewayDomain) + params.InstallDir = strings.TrimSpace(params.InstallDir) + params.Must.Field("clusterId", params.ClusterId).Gt(0, "请选择集群") + params.Must.Field("name", params.Name).Require("请输入集群名称") + params.Must.Field("gatewayDomain", params.GatewayDomain).Require("请输入服务域名") + if params.CacheTtl <= 0 { + params.CacheTtl = 30 + } + if params.FallbackTimeout <= 0 { + params.FallbackTimeout = 300 + } + if len(params.InstallDir) == 0 { + params.InstallDir = "/opt/edge-httpdns" + } if params.IsDefaultCluster && !params.IsOn { this.Fail("默认集群必须保持启用状态") return } - cluster := pickCluster(params.ClusterId) - settings := loadClusterSettings(cluster) - settings["name"] = strings.TrimSpace(params.Name) - settings["gatewayDomain"] = strings.TrimSpace(params.GatewayDomain) - settings["cacheTtl"] = int(params.CacheTtl) - settings["fallbackTimeout"] = int(params.FallbackTimeout) - settings["installDir"] = strings.TrimSpace(params.InstallDir) - settings["isOn"] = params.IsOn - // 处理地址 - var addresses = []*serverconfigs.NetworkAddressConfig{} - if len(params.Addresses) > 0 { - err := json.Unmarshal(params.Addresses, &addresses) - if err != nil { - this.Fail("端口地址解析失败:" + err.Error()) - } - - addressesJSON, _ := json.Marshal(addresses) - settings["listenAddrsJSON"] = string(addressesJSON) + cluster, err := findClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return } - // 处理 SSL 配置 - var originCertPem = "" - var originKeyPem = "" - var tlsMinVersion = "TLS 1.1" - var tlsCipherSuitesOn = false - var tlsOcspOn = false - var tlsClientAuthType = sslconfigs.SSLClientAuthType(0) + tlsConfig := maps.Map{} + if rawTLS := strings.TrimSpace(cluster.GetString("tlsPolicyJSON")); len(rawTLS) > 0 { + _ = json.Unmarshal([]byte(rawTLS), &tlsConfig) + } + + if len(params.Addresses) > 0 { + var addresses []*serverconfigs.NetworkAddressConfig + if err := json.Unmarshal(params.Addresses, &addresses); err != nil { + this.Fail("监听端口配置格式不正确") + return + } + tlsConfig["listen"] = addresses + } if len(params.SslPolicyJSON) > 0 { sslPolicy := &sslconfigs.SSLPolicy{} - err := json.Unmarshal(params.SslPolicyJSON, sslPolicy) - if err == nil { - tlsMinVersion = sslPolicy.MinVersion - tlsCipherSuitesOn = sslPolicy.CipherSuitesIsOn - tlsOcspOn = sslPolicy.OCSPIsOn - tlsClientAuthType = sslconfigs.SSLClientAuthType(sslPolicy.ClientAuthType) + if err := json.Unmarshal(params.SslPolicyJSON, sslPolicy); err != nil { + this.Fail("TLS 配置格式不正确") + return + } + tlsConfig["sslPolicy"] = sslPolicy + } - if len(sslPolicy.Certs) > 0 { - cert := sslPolicy.Certs[0] - originCertPem = string(cert.CertData) - originKeyPem = string(cert.KeyData) - } + var tlsPolicyJSON []byte + if len(tlsConfig) > 0 { + tlsPolicyJSON, err = json.Marshal(tlsConfig) + if err != nil { + this.ErrorPage(err) + return } } - if len(originCertPem) == 0 || len(originKeyPem) == 0 { - this.Fail("请上传或选择证书") - } - - settings["originHttps"] = true - settings["originCertPem"] = originCertPem - settings["originKeyPem"] = originKeyPem - if len(tlsMinVersion) == 0 { - tlsMinVersion = "TLS 1.1" - } - settings["tlsMinVersion"] = tlsMinVersion - settings["tlsCipherSuitesOn"] = tlsCipherSuitesOn - settings["tlsOcspOn"] = tlsOcspOn - settings["tlsClientAuthType"] = int(tlsClientAuthType) - settings["lastModifiedAt"] = nowDateTime() - settings["certUpdatedAt"] = nowDateTime() - - saveClusterSettings(params.ClusterId, settings) - - currentDefaultClusterId := policies.LoadDefaultClusterID() - if params.IsDefaultCluster { - policies.SaveDefaultClusterID(params.ClusterId) - } else if currentDefaultClusterId == params.ClusterId { - policies.SaveDefaultClusterID(0) + _, err = this.RPC().HTTPDNSClusterRPC().UpdateHTTPDNSCluster(this.AdminContext(), &pb.UpdateHTTPDNSClusterRequest{ + ClusterId: params.ClusterId, + Name: params.Name, + ServiceDomain: params.GatewayDomain, + DefaultTTL: params.CacheTtl, + FallbackTimeoutMs: params.FallbackTimeout, + InstallDir: params.InstallDir, + TlsPolicyJSON: tlsPolicyJSON, + IsOn: params.IsOn, + IsDefault: params.IsDefaultCluster, + }) + if err != nil { + this.ErrorPage(err) + return } this.Success() diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/clusterSettings_store.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/clusterSettings_store.go deleted file mode 100644 index f835484..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/clusterSettings_store.go +++ /dev/null @@ -1,110 +0,0 @@ -package clusters - -import ( - "strings" - "sync" - "time" - - "github.com/iwind/TeaGo/maps" -) - -var clusterSettingsStore = struct { - sync.RWMutex - data map[int64]maps.Map -}{ - data: map[int64]maps.Map{}, -} - -func defaultClusterSettings(cluster maps.Map) maps.Map { - installDir := strings.TrimSpace(cluster.GetString("installDir")) - if len(installDir) == 0 { - installDir = "/opt/edge-httpdns" - } - - return maps.Map{ - "name": cluster.GetString("name"), - "gatewayDomain": strings.TrimSpace(cluster.GetString("gatewayDomain")), - "cacheTtl": cluster.GetInt("cacheTtl"), - "fallbackTimeout": cluster.GetInt("fallbackTimeout"), - "installDir": installDir, - "isOn": cluster.GetBool("isOn"), - "originHttps": true, - "originCertPem": "", - "originKeyPem": "", - "tlsMinVersion": "TLS 1.1", - "tlsCipherSuitesOn": false, - "tlsOcspOn": false, - "tlsClientAuthType": 0, - "certUpdatedAt": "", - "lastModifiedAt": "", - } -} - -func cloneClusterSettings(settings maps.Map) maps.Map { - return maps.Map{ - "name": settings.GetString("name"), - "gatewayDomain": settings.GetString("gatewayDomain"), - "cacheTtl": settings.GetInt("cacheTtl"), - "fallbackTimeout": settings.GetInt("fallbackTimeout"), - "installDir": settings.GetString("installDir"), - "isOn": settings.GetBool("isOn"), - "originHttps": true, - "originCertPem": settings.GetString("originCertPem"), - "originKeyPem": settings.GetString("originKeyPem"), - "tlsMinVersion": settings.GetString("tlsMinVersion"), - "tlsCipherSuitesOn": settings.GetBool("tlsCipherSuitesOn"), - "tlsOcspOn": settings.GetBool("tlsOcspOn"), - "tlsClientAuthType": settings.GetInt("tlsClientAuthType"), - "certUpdatedAt": settings.GetString("certUpdatedAt"), - "lastModifiedAt": settings.GetString("lastModifiedAt"), - } -} - -func loadClusterSettings(cluster maps.Map) maps.Map { - clusterId := cluster.GetInt64("id") - - clusterSettingsStore.RLock() - settings, ok := clusterSettingsStore.data[clusterId] - clusterSettingsStore.RUnlock() - if ok { - if len(settings.GetString("tlsMinVersion")) == 0 { - settings["tlsMinVersion"] = "TLS 1.1" - } - return cloneClusterSettings(settings) - } - - settings = defaultClusterSettings(cluster) - saveClusterSettings(clusterId, settings) - return cloneClusterSettings(settings) -} - -func saveClusterSettings(clusterId int64, settings maps.Map) { - clusterSettingsStore.Lock() - clusterSettingsStore.data[clusterId] = cloneClusterSettings(settings) - clusterSettingsStore.Unlock() -} - -func applyClusterSettingsOverrides(cluster maps.Map) { - clusterId := cluster.GetInt64("id") - if clusterId <= 0 { - return - } - - clusterSettingsStore.RLock() - settings, ok := clusterSettingsStore.data[clusterId] - clusterSettingsStore.RUnlock() - if !ok { - return - } - - cluster["name"] = settings.GetString("name") - cluster["gatewayDomain"] = settings.GetString("gatewayDomain") - cluster["cacheTtl"] = settings.GetInt("cacheTtl") - cluster["fallbackTimeout"] = settings.GetInt("fallbackTimeout") - cluster["installDir"] = settings.GetString("installDir") - cluster["isOn"] = settings.GetBool("isOn") -} - -func nowDateTime() string { - return time.Now().Format("2006-01-02 15:04:05") -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/create.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/create.go index e8779f5..af2c55d 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/create.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/create.go @@ -1,8 +1,12 @@ package clusters import ( + "strings" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/actions" ) type CreateAction struct { @@ -17,3 +21,48 @@ func (this *CreateAction) RunGet(params struct{}) { httpdnsutils.AddLeftMenu(this.Parent()) this.Show() } + +func (this *CreateAction) RunPost(params struct { + Name string + GatewayDomain string + CacheTtl int32 + FallbackTimeout int32 + InstallDir string + IsOn bool + IsDefault bool + + Must *actions.Must +}) { + params.Name = strings.TrimSpace(params.Name) + params.GatewayDomain = strings.TrimSpace(params.GatewayDomain) + params.InstallDir = strings.TrimSpace(params.InstallDir) + if len(params.InstallDir) == 0 { + params.InstallDir = "/opt/edge-httpdns" + } + if params.CacheTtl <= 0 { + params.CacheTtl = 30 + } + if params.FallbackTimeout <= 0 { + params.FallbackTimeout = 300 + } + + params.Must.Field("name", params.Name).Require("请输入集群名称") + params.Must.Field("gatewayDomain", params.GatewayDomain).Require("请输入服务域名") + + resp, err := this.RPC().HTTPDNSClusterRPC().CreateHTTPDNSCluster(this.AdminContext(), &pb.CreateHTTPDNSClusterRequest{ + Name: params.Name, + ServiceDomain: params.GatewayDomain, + DefaultTTL: params.CacheTtl, + FallbackTimeoutMs: params.FallbackTimeout, + InstallDir: params.InstallDir, + IsOn: params.IsOn, + IsDefault: params.IsDefault, + }) + if err != nil { + this.ErrorPage(err) + return + } + + this.Data["clusterId"] = resp.GetClusterId() + this.Success() +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/createNode.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/createNode.go index 78f375e..b34fb45 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/createNode.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/createNode.go @@ -1,8 +1,11 @@ package clusters import ( + "strings" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" + "github.com/iwind/TeaGo/actions" ) type CreateNodeAction struct { @@ -13,13 +16,18 @@ func (this *CreateNodeAction) Init() { this.Nav("httpdns", "cluster", "createNode") } -func (this *CreateNodeAction) RunGet(params struct{ ClusterId int64 }) { +func (this *CreateNodeAction) RunGet(params struct { + ClusterId int64 +}) { httpdnsutils.AddLeftMenu(this.Parent()) - cluster := pickCluster(params.ClusterId) - // 构建顶部 tabbar + cluster, err := findClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return + } + httpdnsutils.AddClusterTabbar(this.Parent(), cluster.GetString("name"), params.ClusterId, "node") - this.Data["clusterId"] = params.ClusterId this.Data["cluster"] = cluster this.Show() @@ -28,6 +36,28 @@ func (this *CreateNodeAction) RunGet(params struct{ ClusterId int64 }) { func (this *CreateNodeAction) RunPost(params struct { ClusterId int64 Name string + InstallDir string + + Must *actions.Must }) { + params.Name = strings.TrimSpace(params.Name) + params.InstallDir = strings.TrimSpace(params.InstallDir) + params.Must.Field("clusterId", params.ClusterId).Gt(0, "请选择集群") + params.Must.Field("name", params.Name).Require("请输入节点名称") + + if len(params.InstallDir) == 0 { + cluster, err := findClusterMap(this.Parent(), params.ClusterId) + if err == nil { + params.InstallDir = strings.TrimSpace(cluster.GetString("installDir")) + } + if len(params.InstallDir) == 0 { + params.InstallDir = "/opt/edge-httpdns" + } + } + + if err := createNode(this.Parent(), params.ClusterId, params.Name, params.InstallDir); err != nil { + this.ErrorPage(err) + return + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/delete.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/delete.go index 9081f33..4b624b9 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/delete.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/delete.go @@ -3,6 +3,7 @@ package clusters import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" ) type DeleteAction struct { @@ -17,11 +18,14 @@ func (this *DeleteAction) RunGet(params struct { ClusterId int64 }) { httpdnsutils.AddLeftMenu(this.Parent()) - cluster := pickCluster(params.ClusterId) - // 构建顶部 tabbar + cluster, err := findClusterMap(this.Parent(), params.ClusterId) + if err != nil { + this.ErrorPage(err) + return + } + httpdnsutils.AddClusterTabbar(this.Parent(), cluster.GetString("name"), params.ClusterId, "delete") - this.Data["cluster"] = cluster this.Show() } @@ -29,6 +33,12 @@ func (this *DeleteAction) RunGet(params struct { func (this *DeleteAction) RunPost(params struct { ClusterId int64 }) { - _ = params.ClusterId + _, err := this.RPC().HTTPDNSClusterRPC().DeleteHTTPDNSCluster(this.AdminContext(), &pb.DeleteHTTPDNSClusterRequest{ + ClusterId: params.ClusterId, + }) + if err != nil { + this.ErrorPage(err) + return + } this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/deleteNode.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/deleteNode.go index 7adcd40..eecc635 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/deleteNode.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/deleteNode.go @@ -1,6 +1,18 @@ -package clusters -import ( -"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" -) -type DeleteNodeAction struct { actionutils.ParentAction } -func (this *DeleteNodeAction) RunPost(params struct{ ClusterId int64; NodeId int64 }) { this.Success() } +package clusters + +import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + +type DeleteNodeAction struct { + actionutils.ParentAction +} + +func (this *DeleteNodeAction) RunPost(params struct { + ClusterId int64 + NodeId int64 +}) { + if err := deleteNode(this.Parent(), params.NodeId); err != nil { + this.ErrorPage(err) + return + } + this.Success() +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/index.go index f1ead83..9f2e27b 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/index.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/index.go @@ -13,8 +13,27 @@ func (this *IndexAction) Init() { this.Nav("httpdns", "cluster", "") } -func (this *IndexAction) RunGet(params struct{}) { +func (this *IndexAction) RunGet(params struct { + Keyword string +}) { httpdnsutils.AddLeftMenu(this.Parent()) - this.Data["clusters"] = mockClusters() + this.Data["keyword"] = params.Keyword + + clusters, err := listClusterMaps(this.Parent(), params.Keyword) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["clusters"] = clusters + + hasErrorLogs := false + for _, cluster := range clusters { + if cluster.GetInt("countAllNodes") > cluster.GetInt("countActiveNodes") { + hasErrorLogs = true + break + } + } + this.Data["hasErrorLogs"] = hasErrorLogs + this.Data["page"] = "" this.Show() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/init.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/init.go index bfecd53..999e0ab 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/init.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/init.go @@ -15,7 +15,7 @@ func init() { Data("teaSubMenu", "cluster"). Prefix("/httpdns/clusters"). Get("", new(IndexAction)). - Get("/create", new(CreateAction)). + GetPost("/create", new(CreateAction)). Get("/cluster", new(ClusterAction)). GetPost("/cluster/settings", new(ClusterSettingsAction)). GetPost("/delete", new(DeleteAction)). diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/mock.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/mock.go deleted file mode 100644 index f8e91e7..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/mock.go +++ /dev/null @@ -1,132 +0,0 @@ -package clusters - -import "github.com/iwind/TeaGo/maps" - -func mockClusters() []maps.Map { - clusters := []maps.Map{ - { - "id": int64(1), - "name": "gateway-cn-hz", - "region": "cn-hangzhou", - "gatewayDomain": "gw-hz.httpdns.example.com", - "installDir": "/opt/edge-httpdns", - "countAllNodes": 3, - "countActiveNodes": 3, - "countApps": 5, - "cacheTtl": 30, - "fallbackTimeout": 300, - "isOn": true, - }, - { - "id": int64(2), - "name": "gateway-cn-bj", - "region": "cn-beijing", - "gatewayDomain": "gw-bj.httpdns.example.com", - "installDir": "/opt/edge-httpdns", - "countAllNodes": 3, - "countActiveNodes": 2, - "countApps": 2, - "cacheTtl": 30, - "fallbackTimeout": 300, - "isOn": true, - }, - } - - for _, cluster := range clusters { - applyClusterSettingsOverrides(cluster) - } - - return clusters -} - -func pickCluster(clusterId int64) maps.Map { - clusters := mockClusters() - if clusterId <= 0 { - return clusters[0] - } - for _, c := range clusters { - if c.GetInt64("id") == clusterId { - return c - } - } - return clusters[0] -} - -func mockNodes(clusterId int64, installState int, activeState int, keyword string) []maps.Map { - _ = clusterId - return []maps.Map{ - { - "id": int64(101), - "name": "45.250.184.56", - "isInstalled": true, - "isOn": true, - "isUp": true, - "installStatus": maps.Map{ - "isRunning": false, - "isFinished": true, - "isOk": true, - "error": "", - }, - "status": maps.Map{ - "isActive": true, - "updatedAt": 1700000000, - "hostname": "node-01", - "cpuUsage": 0.0253, - "cpuUsageText": "2.53%", - "memUsage": 0.5972, - "memUsageText": "59.72%", - "load1m": 0.02, - }, - "ipAddresses": []maps.Map{ - { - "id": 1, - "name": "", - "ip": "45.250.184.56", - "canAccess": true, - }, - }, - }, - { - "id": int64(102), - "name": "45.250.184.53", - "isInstalled": true, - "isOn": true, - "isUp": true, - "installStatus": maps.Map{ - "isRunning": false, - "isFinished": true, - "isOk": true, - "error": "", - }, - "status": maps.Map{ - "isActive": true, - "updatedAt": 1700000000, - "hostname": "node-02", - "cpuUsage": 0.0039, - "cpuUsageText": "0.39%", - "memUsage": 0.0355, - "memUsageText": "3.55%", - "load1m": 0.0, - }, - "ipAddresses": []maps.Map{ - { - "id": 2, - "name": "", - "ip": "45.250.184.53", - "canAccess": true, - }, - }, - }, - } -} - -func mockCerts() []maps.Map { - return []maps.Map{ - { - "id": int64(11), - "domain": "resolve.edge.example.com", - "issuer": "Mock CA", - "expiresAt": "2026-12-31 23:59:59", - }, - } -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/rpc_helpers.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/rpc_helpers.go new file mode 100644 index 0000000..968cb16 --- /dev/null +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/rpc_helpers.go @@ -0,0 +1,248 @@ +package clusters + +import ( + "encoding/json" + "fmt" + "strings" + + "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/maps" +) + +func listClusterMaps(parent *actionutils.ParentAction, keyword string) ([]maps.Map, error) { + resp, err := parent.RPC().HTTPDNSClusterRPC().ListHTTPDNSClusters(parent.AdminContext(), &pb.ListHTTPDNSClustersRequest{ + Offset: 0, + Size: 10_000, + Keyword: strings.TrimSpace(keyword), + }) + if err != nil { + return nil, err + } + + result := make([]maps.Map, 0, len(resp.GetClusters())) + for _, cluster := range resp.GetClusters() { + nodesResp, err := parent.RPC().HTTPDNSNodeRPC().ListHTTPDNSNodes(parent.AdminContext(), &pb.ListHTTPDNSNodesRequest{ + ClusterId: cluster.GetId(), + }) + if err != nil { + return nil, err + } + countAllNodes := len(nodesResp.GetNodes()) + countActiveNodes := 0 + for _, node := range nodesResp.GetNodes() { + if node.GetIsOn() && node.GetIsUp() && node.GetIsActive() { + countActiveNodes++ + } + } + + result = append(result, maps.Map{ + "id": cluster.GetId(), + "name": cluster.GetName(), + "gatewayDomain": cluster.GetServiceDomain(), + "defaultTTL": cluster.GetDefaultTTL(), + "fallbackTimeout": cluster.GetFallbackTimeoutMs(), + "installDir": cluster.GetInstallDir(), + "isOn": cluster.GetIsOn(), + "isDefault": cluster.GetIsDefault(), + "countAllNodes": countAllNodes, + "countActiveNodes": countActiveNodes, + }) + } + return result, nil +} + +func findClusterMap(parent *actionutils.ParentAction, clusterID int64) (maps.Map, error) { + if clusterID > 0 { + resp, err := parent.RPC().HTTPDNSClusterRPC().FindHTTPDNSCluster(parent.AdminContext(), &pb.FindHTTPDNSClusterRequest{ + ClusterId: clusterID, + }) + if err != nil { + return nil, err + } + if resp.GetCluster() != nil { + cluster := resp.GetCluster() + return maps.Map{ + "id": cluster.GetId(), + "name": cluster.GetName(), + "gatewayDomain": cluster.GetServiceDomain(), + "defaultTTL": cluster.GetDefaultTTL(), + "fallbackTimeout": cluster.GetFallbackTimeoutMs(), + "installDir": cluster.GetInstallDir(), + "isOn": cluster.GetIsOn(), + "isDefault": cluster.GetIsDefault(), + "tlsPolicyJSON": cluster.GetTlsPolicyJSON(), + }, nil + } + } + + clusters, err := listClusterMaps(parent, "") + if err != nil { + return nil, err + } + if len(clusters) == 0 { + return maps.Map{ + "id": int64(0), + "name": "", + "gatewayDomain": "", + "defaultTTL": 30, + "fallbackTimeout": 300, + "installDir": "/opt/edge-httpdns", + }, nil + } + return clusters[0], nil +} + +func listNodeMaps(parent *actionutils.ParentAction, clusterID int64) ([]maps.Map, error) { + resp, err := parent.RPC().HTTPDNSNodeRPC().ListHTTPDNSNodes(parent.AdminContext(), &pb.ListHTTPDNSNodesRequest{ + ClusterId: clusterID, + }) + if err != nil { + return nil, err + } + + result := make([]maps.Map, 0, len(resp.GetNodes())) + for _, node := range resp.GetNodes() { + statusMap := decodeNodeStatus(node.GetStatusJSON()) + installStatusMap := decodeInstallStatus(node.GetInstallStatusJSON()) + ip := node.GetName() + if parsed := strings.TrimSpace(statusMap.GetString("hostIP")); len(parsed) > 0 { + ip = parsed + } + nodeMap := maps.Map{ + "id": node.GetId(), + "clusterId": node.GetClusterId(), + "name": node.GetName(), + "isOn": node.GetIsOn(), + "isUp": node.GetIsUp(), + "isInstalled": node.GetIsInstalled(), + "isActive": node.GetIsActive(), + "installDir": node.GetInstallDir(), + "uniqueId": node.GetUniqueId(), + "secret": node.GetSecret(), + "status": statusMap, + "installStatus": installStatusMap, + "region": nil, + "login": nil, + "apiNodeAddrs": []string{}, + "cluster": maps.Map{ + "id": node.GetClusterId(), + "installDir": node.GetInstallDir(), + }, + "ipAddresses": []maps.Map{ + { + "id": node.GetId(), + "name": "Public IP", + "ip": ip, + "canAccess": true, + "isOn": node.GetIsOn(), + "isUp": node.GetIsUp(), + }, + }, + } + result = append(result, nodeMap) + } + return result, nil +} + +func findNodeMap(parent *actionutils.ParentAction, nodeID int64) (maps.Map, error) { + resp, err := parent.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(parent.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: nodeID, + }) + if err != nil { + return nil, err + } + if resp.GetNode() == nil { + return maps.Map{}, nil + } + nodes, err := listNodeMaps(parent, resp.GetNode().GetClusterId()) + if err != nil { + return nil, err + } + for _, node := range nodes { + if node.GetInt64("id") == nodeID { + return node, nil + } + } + return maps.Map{ + "id": resp.GetNode().GetId(), + "name": resp.GetNode().GetName(), + }, nil +} + +func createNode(parent *actionutils.ParentAction, clusterID int64, name string, installDir string) error { + _, err := parent.RPC().HTTPDNSNodeRPC().CreateHTTPDNSNode(parent.AdminContext(), &pb.CreateHTTPDNSNodeRequest{ + ClusterId: clusterID, + Name: strings.TrimSpace(name), + InstallDir: strings.TrimSpace(installDir), + IsOn: true, + }) + return err +} + +func updateNode(parent *actionutils.ParentAction, nodeID int64, name string, installDir string, isOn bool) error { + _, err := parent.RPC().HTTPDNSNodeRPC().UpdateHTTPDNSNode(parent.AdminContext(), &pb.UpdateHTTPDNSNodeRequest{ + NodeId: nodeID, + Name: strings.TrimSpace(name), + InstallDir: strings.TrimSpace(installDir), + IsOn: isOn, + }) + return err +} + +func deleteNode(parent *actionutils.ParentAction, nodeID int64) error { + _, err := parent.RPC().HTTPDNSNodeRPC().DeleteHTTPDNSNode(parent.AdminContext(), &pb.DeleteHTTPDNSNodeRequest{ + NodeId: nodeID, + }) + return err +} + +func decodeNodeStatus(raw []byte) maps.Map { + status := &nodeconfigs.NodeStatus{} + if len(raw) > 0 { + _ = json.Unmarshal(raw, status) + } + cpuText := fmt.Sprintf("%.2f%%", status.CPUUsage*100) + memText := fmt.Sprintf("%.2f%%", status.MemoryUsage*100) + return maps.Map{ + "isActive": status.IsActive, + "updatedAt": status.UpdatedAt, + "hostname": status.Hostname, + "hostIP": status.HostIP, + "cpuUsage": status.CPUUsage, + "cpuUsageText": cpuText, + "memUsage": status.MemoryUsage, + "memUsageText": memText, + "load1m": status.Load1m, + "load5m": status.Load5m, + "load15m": status.Load15m, + "buildVersion": status.BuildVersion, + "cpuPhysicalCount": status.CPUPhysicalCount, + "cpuLogicalCount": status.CPULogicalCount, + "exePath": status.ExePath, + } +} + +func decodeInstallStatus(raw []byte) maps.Map { + if len(raw) == 0 { + return maps.Map{ + "isRunning": false, + "isFinished": true, + "isOk": true, + "error": "", + "errorCode": "", + } + } + result := maps.Map{} + if err := json.Unmarshal(raw, &result); err != nil { + return maps.Map{ + "isRunning": false, + "isFinished": true, + "isOk": true, + "error": "", + "errorCode": "", + } + } + return result +} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/updateNodeSSH.go b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/updateNodeSSH.go index f8360e4..789bc98 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/clusters/updateNodeSSH.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/clusters/updateNodeSSH.go @@ -1,7 +1,14 @@ package clusters import ( + "encoding/json" + "net" + "regexp" + "strings" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/iwind/TeaGo/actions" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/maps" ) @@ -12,18 +19,52 @@ type UpdateNodeSSHAction struct { func (this *UpdateNodeSSHAction) RunGet(params struct { NodeId int64 }) { + resp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err != nil { + this.ErrorPage(err) + return + } + + clusterId := int64(0) + nodeName := "" + if resp.GetNode() != nil { + clusterId = resp.GetNode().GetClusterId() + nodeName = resp.GetNode().GetName() + } + this.Data["nodeId"] = params.NodeId - this.Data["clusterId"] = 0 + this.Data["clusterId"] = clusterId this.Data["node"] = maps.Map{ "id": params.NodeId, - "name": "Mock Node", + "name": nodeName, } - this.Data["loginId"] = 0 - this.Data["params"] = maps.Map{ - "host": "1.2.3.4", + loginParams := maps.Map{ + "host": "", "port": 22, "grantId": 0, } + this.Data["loginId"] = 0 + + if resp.GetNode() != nil && len(resp.GetNode().GetInstallStatusJSON()) > 0 { + installStatus := maps.Map{} + _ = json.Unmarshal(resp.GetNode().GetInstallStatusJSON(), &installStatus) + sshInfo := installStatus.GetMap("ssh") + if sshInfo != nil { + if host := strings.TrimSpace(sshInfo.GetString("host")); len(host) > 0 { + loginParams["host"] = host + } + if port := sshInfo.GetInt("port"); port > 0 { + loginParams["port"] = port + } + if grantID := sshInfo.GetInt64("grantId"); grantID > 0 { + loginParams["grantId"] = grantID + } + } + } + + this.Data["params"] = loginParams this.Data["grant"] = nil this.Show() } @@ -34,6 +75,66 @@ func (this *UpdateNodeSSHAction) RunPost(params struct { SshHost string SshPort int GrantId int64 + + Must *actions.Must }) { + params.SshHost = strings.TrimSpace(params.SshHost) + params.Must. + Field("sshHost", params.SshHost). + Require("请输入 SSH 主机地址"). + Field("sshPort", params.SshPort). + Gt(0, "SSH 端口必须大于 0"). + Lt(65535, "SSH 端口必须小于 65535") + if params.GrantId <= 0 { + this.Fail("请选择节点登录认证信息") + } + + if regexp.MustCompile(`^\d+\.\d+\.\d+\.\d+$`).MatchString(params.SshHost) && net.ParseIP(params.SshHost) == nil { + this.Fail("SSH 主机地址 IP 格式错误") + } + + resp, err := this.RPC().HTTPDNSNodeRPC().FindHTTPDNSNode(this.AdminContext(), &pb.FindHTTPDNSNodeRequest{ + NodeId: params.NodeId, + }) + if err != nil { + this.ErrorPage(err) + return + } + node := resp.GetNode() + if node == nil { + this.Fail("节点不存在") + return + } + + installStatus := maps.Map{ + "isRunning": false, + "isFinished": true, + "isOk": node.GetIsInstalled(), + "error": "", + "errorCode": "", + } + if len(node.GetInstallStatusJSON()) > 0 { + _ = json.Unmarshal(node.GetInstallStatusJSON(), &installStatus) + } + installStatus["ssh"] = maps.Map{ + "host": params.SshHost, + "port": params.SshPort, + "grantId": params.GrantId, + } + + installStatusJSON, _ := json.Marshal(installStatus) + _, err = this.RPC().HTTPDNSNodeRPC().UpdateHTTPDNSNodeStatus(this.AdminContext(), &pb.UpdateHTTPDNSNodeStatusRequest{ + NodeId: params.NodeId, + IsUp: node.GetIsUp(), + IsInstalled: node.GetIsInstalled(), + IsActive: node.GetIsActive(), + StatusJSON: node.GetStatusJSON(), + InstallStatusJSON: installStatusJSON, + }) + if err != nil { + this.ErrorPage(err) + return + } + this.Success() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/ech/audit.go b/EdgeAdmin/internal/web/actions/default/httpdns/ech/audit.go index e8f7d74..a9d8c2b 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/ech/audit.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/ech/audit.go @@ -1,9 +1,6 @@ package ech -import ( - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" -) +import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" type AuditAction struct { actionutils.ParentAction @@ -14,15 +11,5 @@ func (this *AuditAction) Init() { } func (this *AuditAction) RunGet(params struct{}) { - httpdnsutils.AddLeftMenu(this.Parent()) - this.Data["auditLogs"] = []map[string]interface{}{ - { - "id": 1, - "scope": "tenant:1001 -> domain:api.business.com -> region:cn-hz", - "operator": "admin", - "result": "success", - "createdAt": "2026-02-21 10:00:00", - }, - } - this.Show() + this.RedirectURL("/httpdns/apps") } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/ech/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/ech/index.go index b33aa5f..76b9832 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/ech/index.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/ech/index.go @@ -1,9 +1,6 @@ package ech -import ( - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" -) +import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" type IndexAction struct { actionutils.ParentAction @@ -14,34 +11,5 @@ func (this *IndexAction) Init() { } func (this *IndexAction) RunGet(params struct{}) { - httpdnsutils.AddLeftMenu(this.Parent()) - this.Data["health"] = map[string]interface{}{ - "keySyncRate": 0.9995, - "decryptFailRate": 0.0001, - "isHealthy": true, - } - - this.Data["echLogs"] = []map[string]interface{}{ - { - "id": 1024, - "version": "ech-v20260221-01", - "recordType": "HTTPS(Type65)", - "publicKey": "BFCf8h5Qmock_public_key_for_ui_preview_lx9v2k7p0n", - "publishTime": "2026-02-21 00:00:00", - "syncStatus": "success", - "nodesPending": 0, - "isCurrent": true, - }, - { - "id": 1023, - "version": "ech-v20260220-01", - "recordType": "TXT", - "publicKey": "BE9x3a2Qmock_prev_key_for_ui_preview_vd1n7x5k2c", - "publishTime": "2026-02-20 00:00:00", - "syncStatus": "success", - "nodesPending": 0, - "isCurrent": false, - }, - } - this.Show() + this.RedirectURL("/httpdns/apps") } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/ech/rollbackMfaPopup.go b/EdgeAdmin/internal/web/actions/default/httpdns/ech/rollbackMfaPopup.go index 4fc36a2..18c35c5 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/ech/rollbackMfaPopup.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/ech/rollbackMfaPopup.go @@ -16,8 +16,7 @@ func (this *RollbackMfaPopupAction) Init() { func (this *RollbackMfaPopupAction) RunGet(params struct { LogId int64 }) { - this.Data["logId"] = params.LogId - this.Show() + this.RedirectURL("/httpdns/apps") } func (this *RollbackMfaPopupAction) RunPost(params struct { @@ -29,8 +28,5 @@ func (this *RollbackMfaPopupAction) RunPost(params struct { Must *actions.Must CSRF *actionutils.CSRF }) { - params.Must.Field("reason", params.Reason).Require("please input rollback reason") - params.Must.Field("otpCode1", params.OtpCode1).Require("please input first otp code") - params.Must.Field("otpCode2", params.OtpCode2).Require("please input second otp code") - this.Success() + this.Fail("feature removed") } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/policies/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/policies/index.go index 102e538..546bcd3 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/policies/index.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/policies/index.go @@ -1,11 +1,6 @@ package policies -import ( - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" - "github.com/iwind/TeaGo/actions" - "github.com/iwind/TeaGo/maps" -) +import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" type IndexAction struct { actionutils.ParentAction @@ -16,52 +11,9 @@ func (this *IndexAction) Init() { } func (this *IndexAction) RunGet(params struct{}) { - httpdnsutils.AddLeftMenu(this.Parent()) - this.Data["policies"] = loadGlobalPolicies() - this.Data["availableClusters"] = loadAvailableDeployClusters() - this.Show() + this.RedirectURL("/httpdns/clusters") } -func (this *IndexAction) RunPost(params struct { - DefaultClusterId int64 - DefaultTTL int - DefaultFallbackMs int - - Must *actions.Must - CSRF *actionutils.CSRF -}) { - if params.DefaultClusterId <= 0 || !isValidClusterID(params.DefaultClusterId) { - this.Fail("please select a valid default cluster") - return - } - - params.Must.Field("defaultTTL", params.DefaultTTL).Gt(0, "default ttl should be > 0") - params.Must.Field("defaultFallbackMs", params.DefaultFallbackMs).Gt(0, "default fallback should be > 0") - - if params.DefaultTTL > 86400 { - this.Fail("default TTL should be <= 86400") - return - } - if params.DefaultFallbackMs > 10000 { - this.Fail("default fallback should be <= 10000 ms") - return - } - - saveGlobalPolicies(maps.Map{ - "defaultClusterId": params.DefaultClusterId, - "enableUserDomainVerify": true, - "defaultTTL": params.DefaultTTL, - "defaultFallbackMs": params.DefaultFallbackMs, - }) - +func (this *IndexAction) RunPost(params struct{}) { this.Success() } - -func isValidClusterID(clusterID int64) bool { - for _, cluster := range loadAvailableDeployClusters() { - if cluster.GetInt64("id") == clusterID { - return true - } - } - return false -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/policies/store.go b/EdgeAdmin/internal/web/actions/default/httpdns/policies/store.go deleted file mode 100644 index b4f4080..0000000 --- a/EdgeAdmin/internal/web/actions/default/httpdns/policies/store.go +++ /dev/null @@ -1,180 +0,0 @@ -package policies - -import ( - "strings" - "sync" - - "github.com/iwind/TeaGo/maps" -) - -var globalPoliciesStore = struct { - sync.RWMutex - data maps.Map - publicSniPools []maps.Map - publicSniCertificates []maps.Map -}{ - data: maps.Map{ - "defaultClusterId": int64(1), - "enableUserDomainVerify": true, - "defaultTTL": 30, - "defaultFallbackMs": 300, - }, - publicSniPools: []maps.Map{ - { - "domain": "public-sni-a.waf.example.com", - "certId": "cert_public_sni_a", - }, - { - "domain": "public-sni-b.waf.example.com", - "certId": "cert_public_sni_b", - }, - }, - publicSniCertificates: []maps.Map{ - { - "id": "cert_public_sni_a", - "name": "public-sni-a.waf.example.com", - "issuer": "Mock CA", - "expiresAt": "2026-12-31 23:59:59", - }, - { - "id": "cert_public_sni_b", - "name": "public-sni-b.waf.example.com", - "issuer": "Mock CA", - "expiresAt": "2027-03-31 23:59:59", - }, - }, -} - -func loadGlobalPolicies() maps.Map { - globalPoliciesStore.RLock() - defer globalPoliciesStore.RUnlock() - - return maps.Map{ - "defaultClusterId": globalPoliciesStore.data.GetInt64("defaultClusterId"), - "enableUserDomainVerify": true, - "defaultTTL": globalPoliciesStore.data.GetInt("defaultTTL"), - "defaultFallbackMs": globalPoliciesStore.data.GetInt("defaultFallbackMs"), - } -} - -func saveGlobalPolicies(policies maps.Map) { - globalPoliciesStore.Lock() - globalPoliciesStore.data = maps.Map{ - "defaultClusterId": policies.GetInt64("defaultClusterId"), - "enableUserDomainVerify": true, - "defaultTTL": policies.GetInt("defaultTTL"), - "defaultFallbackMs": policies.GetInt("defaultFallbackMs"), - } - - globalPoliciesStore.Unlock() -} - -func loadPublicSNICertificates() []maps.Map { - globalPoliciesStore.RLock() - defer globalPoliciesStore.RUnlock() - - return cloneMapSlice(globalPoliciesStore.publicSniCertificates) -} - -// LoadPublicSNICertificates returns global public SNI certificates for other httpdns modules. -func LoadPublicSNICertificates() []maps.Map { - return loadPublicSNICertificates() -} - -func loadAvailableDeployClusters() []maps.Map { - return []maps.Map{ - { - "id": int64(1), - "name": "gateway-cn-hz", - "region": "cn-hangzhou", - "gatewayDomain": "gw-hz.httpdns.example.com", - }, - { - "id": int64(2), - "name": "gateway-cn-bj", - "region": "cn-beijing", - "gatewayDomain": "gw-bj.httpdns.example.com", - }, - } -} - -// LoadAvailableDeployClusters returns selectable clusters for HTTPDNS user defaults. -func LoadAvailableDeployClusters() []maps.Map { - return loadAvailableDeployClusters() -} - -// LoadDefaultClusterID returns current default deploy cluster id for HTTPDNS users. -func LoadDefaultClusterID() int64 { - globalPoliciesStore.RLock() - defer globalPoliciesStore.RUnlock() - return globalPoliciesStore.data.GetInt64("defaultClusterId") -} - -// SaveDefaultClusterID updates default deploy cluster id. -// Pass 0 to clear and let caller fallback to first available cluster. -func SaveDefaultClusterID(clusterID int64) { - globalPoliciesStore.Lock() - globalPoliciesStore.data["defaultClusterId"] = clusterID - globalPoliciesStore.Unlock() -} - -// LoadClusterGatewayByID returns gateway domain for the selected cluster. -func LoadClusterGatewayByID(clusterID int64) string { - clusters := loadAvailableDeployClusters() - for _, cluster := range clusters { - if cluster.GetInt64("id") == clusterID { - gatewayDomain := strings.TrimSpace(cluster.GetString("gatewayDomain")) - if len(gatewayDomain) > 0 { - return gatewayDomain - } - } - } - - if len(clusters) > 0 { - fallback := strings.TrimSpace(clusters[0].GetString("gatewayDomain")) - if len(fallback) > 0 { - return fallback - } - } - - return "gw.httpdns.example.com" -} - -// LoadPublicSNIPools returns global public SNI domain pool for other httpdns modules. -func LoadPublicSNIPools() []maps.Map { - globalPoliciesStore.RLock() - defer globalPoliciesStore.RUnlock() - - return cloneMapSlice(globalPoliciesStore.publicSniPools) -} - -// HasPublicSNIDomain checks if a public SNI domain exists in global pool. -func HasPublicSNIDomain(domain string) bool { - domain = strings.ToLower(strings.TrimSpace(domain)) - if len(domain) == 0 { - return false - } - - globalPoliciesStore.RLock() - defer globalPoliciesStore.RUnlock() - - for _, pool := range globalPoliciesStore.publicSniPools { - if strings.ToLower(strings.TrimSpace(pool.GetString("domain"))) == domain { - return true - } - } - - return false -} - -func cloneMapSlice(src []maps.Map) []maps.Map { - result := make([]maps.Map, 0, len(src)) - for _, item := range src { - cloned := maps.Map{} - for k, v := range item { - cloned[k] = v - } - result = append(result, cloned) - } - return result -} diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/resolveLogs/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/resolveLogs/index.go index eac62f1..2dbf574 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/resolveLogs/index.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/resolveLogs/index.go @@ -5,6 +5,8 @@ import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + timeutil "github.com/iwind/TeaGo/utils/time" ) type IndexAction struct { @@ -40,120 +42,88 @@ func (this *IndexAction) RunGet(params struct { this.Data["status"] = params.Status this.Data["keyword"] = params.Keyword - clusters := []map[string]interface{}{ - {"id": int64(1), "name": "gateway-cn-hz"}, - {"id": int64(2), "name": "gateway-cn-bj"}, + clusterResp, err := this.RPC().HTTPDNSClusterRPC().FindAllHTTPDNSClusters(this.AdminContext(), &pb.FindAllHTTPDNSClustersRequest{}) + if err != nil { + this.ErrorPage(err) + return } - nodes := []map[string]interface{}{ - {"id": int64(101), "clusterId": int64(1), "name": "hz-node-01"}, - {"id": int64(102), "clusterId": int64(1), "name": "hz-node-02"}, - {"id": int64(201), "clusterId": int64(2), "name": "bj-node-01"}, + clusters := make([]map[string]interface{}, 0, len(clusterResp.GetClusters())) + nodes := make([]map[string]interface{}, 0) + for _, cluster := range clusterResp.GetClusters() { + clusters = append(clusters, map[string]interface{}{ + "id": cluster.GetId(), + "name": cluster.GetName(), + }) + nodeResp, err := this.RPC().HTTPDNSNodeRPC().ListHTTPDNSNodes(this.AdminContext(), &pb.ListHTTPDNSNodesRequest{ + ClusterId: cluster.GetId(), + }) + if err != nil { + this.ErrorPage(err) + return + } + for _, node := range nodeResp.GetNodes() { + nodes = append(nodes, map[string]interface{}{ + "id": node.GetId(), + "clusterId": node.GetClusterId(), + "name": node.GetName(), + }) + } } this.Data["clusters"] = clusters this.Data["nodes"] = nodes - allLogs := []map[string]interface{}{ - { - "time": "2026-02-23 10:21:51", - "clusterId": int64(1), - "clusterName": "gateway-cn-hz", - "nodeId": int64(101), - "nodeName": "hz-node-01", - "appName": "\u4e3b\u7ad9\u79fb\u52a8\u4e1a\u52a1", - "appId": "ab12xc34s2", - "domain": "api.business.com", - "query": "A", - "clientIp": "203.0.113.25", - "os": "Android", - "sdkVersion": "2.4.1", - "ips": "198.51.100.10,198.51.100.11", - "status": "success", - "errorCode": "none", - "costMs": 37, - "pinningMode": "report", - "pinningResult": "warn", - "sanMode": "strict", - "sanResult": "pass", - }, - { - "time": "2026-02-23 10:18:02", - "clusterId": int64(2), - "clusterName": "gateway-cn-bj", - "nodeId": int64(201), - "nodeName": "bj-node-01", - "appName": "\u652f\u4ed8\u7f51\u5173\u4e1a\u52a1", - "appId": "vd8992ksm1", - "domain": "payment.business.com", - "query": "A", - "clientIp": "198.51.100.67", - "os": "iOS", - "sdkVersion": "2.3.9", - "ips": "198.51.100.22", - "status": "failed", - "errorCode": "40301", - "costMs": 52, - "pinningMode": "enforce", - "pinningResult": "fail", - "sanMode": "strict", - "sanResult": "fail", - }, - { - "time": "2026-02-23 10:12:44", - "clusterId": int64(1), - "clusterName": "gateway-cn-hz", - "nodeId": int64(102), - "nodeName": "hz-node-02", - "appName": "\u4e3b\u7ad9\u79fb\u52a8\u4e1a\u52a1", - "appId": "ab12xc34s2", - "domain": "www.aliyun.com", - "query": "A", - "clientIp": "106.11.63.180", - "os": "Unknown", - "sdkVersion": "none", - "ips": "3.33.120.190,15.197.120.33", - "status": "success", - "errorCode": "none", - "costMs": 41, - "pinningMode": "off", - "pinningResult": "na", - "sanMode": "report", - "sanResult": "warn", - }, + logResp, err := this.RPC().HTTPDNSAccessLogRPC().ListHTTPDNSAccessLogs(this.AdminContext(), &pb.ListHTTPDNSAccessLogsRequest{ + Day: "", + ClusterId: params.ClusterId, + NodeId: params.NodeId, + AppId: strings.TrimSpace(params.AppId), + Domain: strings.TrimSpace(params.Domain), + Status: strings.TrimSpace(params.Status), + Keyword: strings.TrimSpace(params.Keyword), + Offset: 0, + Size: 100, + }) + if err != nil { + this.ErrorPage(err) + return } - status := strings.TrimSpace(strings.ToLower(params.Status)) - appID := strings.TrimSpace(strings.ToLower(params.AppId)) - domain := strings.TrimSpace(strings.ToLower(params.Domain)) - keyword := strings.TrimSpace(strings.ToLower(params.Keyword)) + logs := make([]map[string]interface{}, 0, len(logResp.GetLogs())) + for _, item := range logResp.GetLogs() { + createdTime := "" + if item.GetCreatedAt() > 0 { + createdTime = timeutil.FormatTime("Y-m-d H:i:s", item.GetCreatedAt()) + } + status := item.GetStatus() + if len(status) == 0 { + status = "failed" + } + errorCode := item.GetErrorCode() + if len(errorCode) == 0 { + errorCode = "none" + } - filtered := make([]map[string]interface{}, 0) - for _, log := range allLogs { - if params.ClusterId > 0 && log["clusterId"].(int64) != params.ClusterId { - continue - } - if params.NodeId > 0 && log["nodeId"].(int64) != params.NodeId { - continue - } - if len(status) > 0 && log["status"].(string) != status { - continue - } - if len(appID) > 0 && !strings.Contains(strings.ToLower(log["appId"].(string)), appID) { - continue - } - if len(domain) > 0 && !strings.Contains(strings.ToLower(log["domain"].(string)), domain) { - continue - } - if len(keyword) > 0 { - if !strings.Contains(strings.ToLower(log["appName"].(string)), keyword) && - !strings.Contains(strings.ToLower(log["domain"].(string)), keyword) && - !strings.Contains(strings.ToLower(log["clientIp"].(string)), keyword) && - !strings.Contains(strings.ToLower(log["ips"].(string)), keyword) { - continue - } - } - filtered = append(filtered, log) + logs = append(logs, map[string]interface{}{ + "time": createdTime, + "clusterId": item.GetClusterId(), + "clusterName": item.GetClusterName(), + "nodeId": item.GetNodeId(), + "nodeName": item.GetNodeName(), + "appName": item.GetAppName(), + "appId": item.GetAppId(), + "domain": item.GetDomain(), + "query": item.GetQtype(), + "clientIp": item.GetClientIP(), + "os": item.GetOs(), + "sdkVersion": item.GetSdkVersion(), + "ips": item.GetResultIPs(), + "status": status, + "errorCode": errorCode, + "costMs": item.GetCostMs(), + }) } - this.Data["resolveLogs"] = filtered + this.Data["resolveLogs"] = logs this.Show() } + diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/runtimeLogs/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/runtimeLogs/index.go index 9ccb264..6d2071e 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/runtimeLogs/index.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/runtimeLogs/index.go @@ -5,6 +5,8 @@ import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + timeutil "github.com/iwind/TeaGo/utils/time" ) type IndexAction struct { @@ -40,105 +42,75 @@ func (this *IndexAction) RunGet(params struct { this.Data["level"] = params.Level this.Data["keyword"] = params.Keyword - clusters := []map[string]interface{}{ - {"id": int64(1), "name": "gateway-cn-hz"}, - {"id": int64(2), "name": "gateway-cn-bj"}, + clusterResp, err := this.RPC().HTTPDNSClusterRPC().FindAllHTTPDNSClusters(this.AdminContext(), &pb.FindAllHTTPDNSClustersRequest{}) + if err != nil { + this.ErrorPage(err) + return } - nodes := []map[string]interface{}{ - {"id": int64(101), "clusterId": int64(1), "name": "hz-node-01"}, - {"id": int64(102), "clusterId": int64(1), "name": "hz-node-02"}, - {"id": int64(201), "clusterId": int64(2), "name": "bj-node-01"}, + clusters := make([]map[string]interface{}, 0, len(clusterResp.GetClusters())) + nodes := make([]map[string]interface{}, 0) + for _, cluster := range clusterResp.GetClusters() { + clusters = append(clusters, map[string]interface{}{ + "id": cluster.GetId(), + "name": cluster.GetName(), + }) + nodeResp, err := this.RPC().HTTPDNSNodeRPC().ListHTTPDNSNodes(this.AdminContext(), &pb.ListHTTPDNSNodesRequest{ + ClusterId: cluster.GetId(), + }) + if err != nil { + this.ErrorPage(err) + return + } + for _, node := range nodeResp.GetNodes() { + nodes = append(nodes, map[string]interface{}{ + "id": node.GetId(), + "clusterId": node.GetClusterId(), + "name": node.GetName(), + }) + } } this.Data["clusters"] = clusters this.Data["nodes"] = nodes - allLogs := []map[string]interface{}{ - { - "createdTime": "2026-02-23 10:30:12", - "clusterId": int64(1), - "clusterName": "gateway-cn-hz", - "nodeId": int64(101), - "nodeName": "hz-node-01", - "level": "info", - "tag": "config", - "module": "resolver", - "description": "\u914d\u7f6e\u70ed\u52a0\u8f7d\u5b8c\u6210\uff0c\u5df2\u542f\u7528\u6700\u65b0\u7b56\u7565\u5feb\u7167\u3002", - "count": int64(1), - "requestId": "rid-20260223-001", - }, - { - "createdTime": "2026-02-23 10:27:38", - "clusterId": int64(2), - "clusterName": "gateway-cn-bj", - "nodeId": int64(201), - "nodeName": "bj-node-01", - "level": "warning", - "tag": "sni", - "module": "policy-engine", - "description": "\u68c0\u6d4b\u5230 level3 \u6761\u4ef6\u4e0d\u6ee1\u8db3\uff0c\u81ea\u52a8\u964d\u7ea7\u5230 level2\u3002", - "count": int64(3), - "requestId": "rid-20260223-002", - }, - { - "createdTime": "2026-02-23 10:22:49", - "clusterId": int64(1), - "clusterName": "gateway-cn-hz", - "nodeId": int64(102), - "nodeName": "hz-node-02", - "level": "success", - "tag": "cache-refresh", - "module": "cache", - "description": "\u57df\u540d\u7f13\u5b58\u5237\u65b0\u4efb\u52a1\u5b8c\u6210\uff0c\u6210\u529f 2/2\u3002", - "count": int64(1), - "requestId": "rid-20260223-003", - }, - { - "createdTime": "2026-02-23 10:18:11", - "clusterId": int64(1), - "clusterName": "gateway-cn-hz", - "nodeId": int64(101), - "nodeName": "hz-node-01", - "level": "error", - "tag": "upstream", - "module": "resolver", - "description": "\u4e0a\u6e38\u6743\u5a01 DNS \u8bf7\u6c42\u8d85\u65f6\uff0c\u89e6\u53d1\u91cd\u8bd5\u540e\u6062\u590d\u3002", - "count": int64(2), - "requestId": "rid-20260223-004", - }, + day := strings.TrimSpace(params.DayFrom) + if len(day) == 0 { + day = strings.TrimSpace(params.DayTo) + } + logResp, err := this.RPC().HTTPDNSRuntimeLogRPC().ListHTTPDNSRuntimeLogs(this.AdminContext(), &pb.ListHTTPDNSRuntimeLogsRequest{ + Day: day, + ClusterId: params.ClusterId, + NodeId: params.NodeId, + Level: strings.TrimSpace(params.Level), + Keyword: strings.TrimSpace(params.Keyword), + Offset: 0, + Size: 100, + }) + if err != nil { + this.ErrorPage(err) + return } - keyword := strings.TrimSpace(strings.ToLower(params.Keyword)) - filtered := make([]map[string]interface{}, 0) - for _, log := range allLogs { - if params.ClusterId > 0 && log["clusterId"].(int64) != params.ClusterId { - continue + runtimeLogs := make([]map[string]interface{}, 0, len(logResp.GetLogs())) + for _, item := range logResp.GetLogs() { + createdTime := "" + if item.GetCreatedAt() > 0 { + createdTime = timeutil.FormatTime("Y-m-d H:i:s", item.GetCreatedAt()) } - if params.NodeId > 0 && log["nodeId"].(int64) != params.NodeId { - continue - } - if len(params.Level) > 0 && log["level"].(string) != params.Level { - continue - } - if len(params.DayFrom) > 0 { - if log["createdTime"].(string)[:10] < params.DayFrom { - continue - } - } - if len(params.DayTo) > 0 { - if log["createdTime"].(string)[:10] > params.DayTo { - continue - } - } - if len(keyword) > 0 { - if !strings.Contains(strings.ToLower(log["tag"].(string)), keyword) && - !strings.Contains(strings.ToLower(log["description"].(string)), keyword) && - !strings.Contains(strings.ToLower(log["nodeName"].(string)), keyword) { - continue - } - } - filtered = append(filtered, log) + runtimeLogs = append(runtimeLogs, map[string]interface{}{ + "createdTime": createdTime, + "clusterId": item.GetClusterId(), + "clusterName": item.GetClusterName(), + "nodeId": item.GetNodeId(), + "nodeName": item.GetNodeName(), + "level": item.GetLevel(), + "tag": item.GetType(), + "module": item.GetModule(), + "description": item.GetDescription(), + "count": item.GetCount(), + "requestId": item.GetRequestId(), + }) } - - this.Data["runtimeLogs"] = filtered + this.Data["runtimeLogs"] = runtimeLogs this.Show() } + diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/sandbox/index.go b/EdgeAdmin/internal/web/actions/default/httpdns/sandbox/index.go index 4109d16..243c8e5 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/sandbox/index.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/sandbox/index.go @@ -3,7 +3,8 @@ package sandbox import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/policies" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/maps" ) type IndexAction struct { @@ -17,29 +18,48 @@ func (this *IndexAction) Init() { func (this *IndexAction) RunGet(params struct{}) { httpdnsutils.AddLeftMenu(this.Parent()) - this.Data["clusters"] = policies.LoadAvailableDeployClusters() - this.Data["apps"] = []map[string]interface{}{ - { - "id": int64(1), - "name": "主站移动业务", - "appId": "ab12xc34s2", - "clusterId": int64(1), - "domains": []string{"api.business.com", "www.aliyun.com"}, - }, - { - "id": int64(2), - "name": "支付网关业务", - "appId": "vd8992ksm1", - "clusterId": int64(2), - "domains": []string{"payment.business.com"}, - }, - { - "id": int64(3), - "name": "海外灰度测试", - "appId": "ov7711hkq9", - "clusterId": int64(1), - "domains": []string{"global.example.com", "edge.example.com"}, - }, + clusterResp, err := this.RPC().HTTPDNSClusterRPC().FindAllHTTPDNSClusters(this.AdminContext(), &pb.FindAllHTTPDNSClustersRequest{}) + if err != nil { + this.ErrorPage(err) + return } + clusters := make([]maps.Map, 0, len(clusterResp.GetClusters())) + for _, cluster := range clusterResp.GetClusters() { + clusters = append(clusters, maps.Map{ + "id": cluster.GetId(), + "name": cluster.GetName(), + }) + } + this.Data["clusters"] = clusters + + appResp, err := this.RPC().HTTPDNSAppRPC().FindAllHTTPDNSApps(this.AdminContext(), &pb.FindAllHTTPDNSAppsRequest{}) + if err != nil { + this.ErrorPage(err) + return + } + apps := make([]maps.Map, 0, len(appResp.GetApps())) + for _, app := range appResp.GetApps() { + domainResp, err := this.RPC().HTTPDNSDomainRPC().ListHTTPDNSDomainsWithAppId(this.AdminContext(), &pb.ListHTTPDNSDomainsWithAppIdRequest{ + AppDbId: app.GetId(), + }) + if err != nil { + this.ErrorPage(err) + return + } + domains := make([]string, 0, len(domainResp.GetDomains())) + for _, domain := range domainResp.GetDomains() { + domains = append(domains, domain.GetDomain()) + } + apps = append(apps, maps.Map{ + "id": app.GetId(), + "name": app.GetName(), + "appId": app.GetAppId(), + "clusterId": app.GetPrimaryClusterId(), + "primaryClusterId": app.GetPrimaryClusterId(), + "backupClusterId": app.GetBackupClusterId(), + "domains": domains, + }) + } + this.Data["apps"] = apps this.Show() } diff --git a/EdgeAdmin/internal/web/actions/default/httpdns/sandbox/test.go b/EdgeAdmin/internal/web/actions/default/httpdns/sandbox/test.go index 24117ea..7eab116 100644 --- a/EdgeAdmin/internal/web/actions/default/httpdns/sandbox/test.go +++ b/EdgeAdmin/internal/web/actions/default/httpdns/sandbox/test.go @@ -1,13 +1,19 @@ package sandbox import ( - "net" + "crypto/hmac" + "crypto/sha256" + "encoding/hex" "net/url" "strconv" + "strings" + "time" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" - "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/policies" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/index/loginutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/maps" + "github.com/iwind/TeaGo/rands" ) type TestAction struct { @@ -21,96 +27,125 @@ func (this *TestAction) RunPost(params struct { ClientIp string Qtype string }) { - if len(params.ClientIp) == 0 { - params.ClientIp = "203.0.113.100" + clientIP := strings.TrimSpace(params.ClientIp) + if len(clientIP) == 0 { + clientIP = strings.TrimSpace(loginutils.RemoteIP(&this.ActionObject)) + } + qtype := strings.ToUpper(strings.TrimSpace(params.Qtype)) + if len(qtype) == 0 { + qtype = "A" } - clientSubnet := this.maskSubnet(params.ClientIp, 24, 56) - if len(clientSubnet) == 0 { - clientSubnet = "203.0.113.0/24" + resp, err := this.RPC().HTTPDNSSandboxRPC().TestHTTPDNSResolve(this.AdminContext(), &pb.TestHTTPDNSResolveRequest{ + ClusterId: params.ClusterId, + AppId: strings.TrimSpace(params.AppId), + Domain: strings.TrimSpace(params.Domain), + Qtype: qtype, + ClientIP: clientIP, + Sid: "", + SdkVersion: "", + Os: "", + }) + if err != nil { + this.ErrorPage(err) + return } - sniPolicy := "empty" - publicSNI := "" - ecsMode := "off" - ecsIPv4Prefix := 24 - ecsIPv6Prefix := 56 - pinningMode := "off" - sanMode := "off" + clusterDomain := "" + if params.ClusterId > 0 { + clusterResp, findErr := this.RPC().HTTPDNSClusterRPC().FindHTTPDNSCluster(this.AdminContext(), &pb.FindHTTPDNSClusterRequest{ + ClusterId: params.ClusterId, + }) + if findErr == nil && clusterResp.GetCluster() != nil { + clusterDomain = strings.TrimSpace(clusterResp.GetCluster().GetServiceDomain()) + } + } + if len(clusterDomain) == 0 { + clusterDomain = "httpdns.example.com" + } query := url.Values{} query.Set("appId", params.AppId) query.Set("dn", params.Domain) - query.Set("cip", params.ClientIp) - query.Set("qtype", params.Qtype) - clusterServiceDomain := policies.LoadClusterGatewayByID(params.ClusterId) - if len(clusterServiceDomain) == 0 { - clusterServiceDomain = "gw.httpdns.example.com" + query.Set("qtype", qtype) + if len(clientIP) > 0 { + query.Set("cip", clientIP) + } + + signEnabled, signSecret := this.findAppSignConfig(params.AppId) + if signEnabled && len(signSecret) > 0 { + exp := strconv.FormatInt(time.Now().Unix()+300, 10) + nonce := "sandbox-" + rands.HexString(16) + sign := buildSandboxResolveSign(signSecret, params.AppId, params.Domain, qtype, exp, nonce) + query.Set("exp", exp) + query.Set("nonce", nonce) + query.Set("sign", sign) + } + requestURL := "https://" + clusterDomain + "/resolve?" + query.Encode() + + resultCode := 1 + if strings.EqualFold(resp.GetCode(), "SUCCESS") { + resultCode = 0 + } + rows := make([]maps.Map, 0, len(resp.GetRecords())) + ips := make([]string, 0, len(resp.GetRecords())) + lineName := strings.TrimSpace(resp.GetClientCarrier()) + if len(lineName) == 0 { + lineName = "-" + } + for _, record := range resp.GetRecords() { + ips = append(ips, record.GetIp()) + if lineName == "-" && len(record.GetLine()) > 0 { + lineName = record.GetLine() + } + rows = append(rows, maps.Map{ + "domain": resp.GetDomain(), + "type": record.GetType(), + "ip": record.GetIp(), + "ttl": record.GetTtl(), + "region": record.GetRegion(), + "line": record.GetLine(), + }) } - requestURL := "https://" + clusterServiceDomain + "/resolve?" + query.Encode() this.Data["result"] = maps.Map{ - "code": 0, - "message": "ok (mock)", - "requestId": "mock-rid-20260221-001", + "code": resultCode, + "message": resp.GetMessage(), + "requestId": resp.GetRequestId(), "data": maps.Map{ "request_url": requestURL, - "client_ip": params.ClientIp, - "client_region": "中国, 上海, 上海", - "line_name": "默认线路", - "ips": []string{"203.0.113.10", "203.0.113.11"}, - "records": []maps.Map{ - { - "domain": params.Domain, - "type": params.Qtype, - "ip": "203.0.113.10", - "ttl": 30, - "region": "中国-上海-上海", - "line": "默认线路", - }, - { - "domain": params.Domain, - "type": params.Qtype, - "ip": "203.0.113.11", - "ttl": 30, - "region": "中国-上海-上海", - "line": "默认线路", - }, - }, - "ttl": 30, - "sni_policy": sniPolicy, - "public_sni": publicSNI, - "client_subnet": clientSubnet, - "ecs_mode": ecsMode, - "ecs_ipv4_prefix": ecsIPv4Prefix, - "ecs_ipv6_prefix": ecsIPv6Prefix, - "pinning_mode": pinningMode, - "san_mode": sanMode, - "fingerprint_algo": "sha256", - "cert_fingerprints": []string{"8f41ab8d32fca7f9a2b0fdd09a0e2ccf31e5579cd3a0b65f1a9f2f2ec8f38d4a"}, - "verify_headers": maps.Map{ - "X-Edge-Resolve-AppId": params.AppId, - "X-Edge-Resolve-Expire": "1768953600", - "X-Edge-Resolve-Nonce": "mock-nonce-123456", - "X-Edge-Resolve-Target": params.Domain, - "X-Edge-Resolve-Sign": "mock-signature-base64url", - }, + "client_ip": resp.GetClientIP(), + "client_region": resp.GetClientRegion(), + "line_name": lineName, + "ips": ips, + "records": rows, + "ttl": resp.GetTtl(), }, } this.Success() } -func (this *TestAction) maskSubnet(ip string, ipv4Prefix int, ipv6Prefix int) string { - parsed := net.ParseIP(ip) - if parsed == nil { - return "" +func (this *TestAction) findAppSignConfig(appId string) (bool, string) { + appId = strings.TrimSpace(appId) + if len(appId) == 0 { + return false, "" } - ipv4 := parsed.To4() - if ipv4 != nil { - mask := net.CIDRMask(ipv4Prefix, 32) - return ipv4.Mask(mask).String() + "/" + strconv.Itoa(ipv4Prefix) + resp, err := this.RPC().HTTPDNSAppRPC().FindAllHTTPDNSApps(this.AdminContext(), &pb.FindAllHTTPDNSAppsRequest{}) + if err != nil { + return false, "" } - mask := net.CIDRMask(ipv6Prefix, 128) - return parsed.Mask(mask).String() + "/" + strconv.Itoa(ipv6Prefix) + for _, app := range resp.GetApps() { + if strings.EqualFold(strings.TrimSpace(app.GetAppId()), appId) { + return app.GetSignEnabled(), strings.TrimSpace(app.GetSignSecret()) + } + } + return false, "" +} + +func buildSandboxResolveSign(signSecret string, appID string, domain string, qtype string, exp string, nonce string) string { + raw := strings.TrimSpace(appID) + "|" + strings.ToLower(strings.TrimSpace(domain)) + "|" + strings.ToUpper(strings.TrimSpace(qtype)) + "|" + strings.TrimSpace(exp) + "|" + strings.TrimSpace(nonce) + mac := hmac.New(sha256.New, []byte(strings.TrimSpace(signSecret))) + _, _ = mac.Write([]byte(raw)) + return hex.EncodeToString(mac.Sum(nil)) } diff --git a/EdgeAdmin/internal/web/import.go b/EdgeAdmin/internal/web/import.go index 10f2c89..73167f8 100644 --- a/EdgeAdmin/internal/web/import.go +++ b/EdgeAdmin/internal/web/import.go @@ -141,9 +141,7 @@ 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/ech" - _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/guide" - _ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/policies" + _ "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/test_db.go b/EdgeAdmin/test_db.go new file mode 100644 index 0000000..02ecb46 --- /dev/null +++ b/EdgeAdmin/test_db.go @@ -0,0 +1 @@ +package main; import ("fmt"; "github.com/TeaOSLab/EdgeAPI/internal/db/models"; "github.com/iwind/TeaGo/dbs"; "github.com/iwind/TeaGo/Tea"); func main() { Tea.Env = "prod"; dbs.OnReady(func(){ apps, _ := models.SharedHTTPDNSAppDAO.FindAllEnabledApps(nil); for _, app := range apps { fmt.Printf("App: %s, Primary: %d\n", app.AppId, app.PrimaryClusterId) } }); } diff --git a/EdgeAdmin/test_db2.go b/EdgeAdmin/test_db2.go new file mode 100644 index 0000000..9f26f1c --- /dev/null +++ b/EdgeAdmin/test_db2.go @@ -0,0 +1 @@ +package main; import ("fmt"; "github.com/TeaOSLab/EdgeAPI/internal/db/models"; _ "github.com/go-sql-driver/mysql"; "github.com/iwind/TeaGo/dbs"; "github.com/iwind/TeaGo/Tea"); func main() { Tea.Env = "prod"; dbConfig := &dbs.Config{Driver: "mysql", Dsn: "edge:123456@tcp(127.0.0.1:3306)/edge?charset=utf8mb4&parseTime=true&loc=Local", Prefix: "edge"}; dbs.DefaultDB(dbConfig); apps, _ := models.SharedHTTPDNSAppDAO.FindAllEnabledApps(nil); for _, app := range apps { fmt.Printf("App: %s, Primary: %d\n", app.AppId, app.PrimaryClusterId) } } diff --git a/EdgeAdmin/web/views/@default/httpdns/apps/@menu.html b/EdgeAdmin/web/views/@default/httpdns/apps/@menu.html index 3e06600..dda96cc 100644 --- a/EdgeAdmin/web/views/@default/httpdns/apps/@menu.html +++ b/EdgeAdmin/web/views/@default/httpdns/apps/@menu.html @@ -1,4 +1,4 @@ 应用列表 - [添加应用] - + [添加应用] + \ No newline at end of file diff --git a/EdgeAdmin/web/views/@default/httpdns/apps/createPopup.html b/EdgeAdmin/web/views/@default/httpdns/apps/create.html similarity index 74% rename from EdgeAdmin/web/views/@default/httpdns/apps/createPopup.html rename to EdgeAdmin/web/views/@default/httpdns/apps/create.html index e28341e..c18f4e4 100644 --- a/EdgeAdmin/web/views/@default/httpdns/apps/createPopup.html +++ b/EdgeAdmin/web/views/@default/httpdns/apps/create.html @@ -1,8 +1,7 @@ -{$layout "layout_popup"} +{$layout} +{$template "menu"} -

添加应用

- -
+ @@ -35,13 +34,10 @@
所属用户 - -

可分配给指定租户用户;留空表示平台管理员自用。

+ +

可以选择当前应用所属的平台用户。

-
+ \ No newline at end of file diff --git a/EdgeAdmin/web/views/@default/httpdns/apps/create.js b/EdgeAdmin/web/views/@default/httpdns/apps/create.js new file mode 100644 index 0000000..79b655f Binary files /dev/null and b/EdgeAdmin/web/views/@default/httpdns/apps/create.js differ diff --git a/EdgeAdmin/web/views/@default/httpdns/apps/customRecords.js b/EdgeAdmin/web/views/@default/httpdns/apps/customRecords.js index aee143c..cd65c73 100644 --- a/EdgeAdmin/web/views/@default/httpdns/apps/customRecords.js +++ b/EdgeAdmin/web/views/@default/httpdns/apps/customRecords.js @@ -10,7 +10,12 @@ teaweb.popup("/httpdns/apps/customRecords/createPopup?appId=" + this.app.id + "&domainId=" + this.domain.id, { width: "42em", height: "33em", - title: "新增自定义解析规则" + title: "新增自定义解析规则", + callback: function () { + teaweb.success("保存成功", function () { + teaweb.reload(); + }); + } }); }; @@ -21,7 +26,12 @@ teaweb.popup("/httpdns/apps/customRecords/createPopup?appId=" + this.app.id + "&domainId=" + this.domain.id + "&recordId=" + recordId, { width: "42em", height: "33em", - title: "编辑自定义解析规则" + title: "编辑自定义解析规则", + callback: function () { + teaweb.success("保存成功", function () { + teaweb.reload(); + }); + } }); }; diff --git a/EdgeAdmin/web/views/@default/httpdns/apps/customRecordsCreatePopup.html b/EdgeAdmin/web/views/@default/httpdns/apps/customRecordsCreatePopup.html index 68b8a6d..c286ddc 100644 --- a/EdgeAdmin/web/views/@default/httpdns/apps/customRecordsCreatePopup.html +++ b/EdgeAdmin/web/views/@default/httpdns/apps/customRecordsCreatePopup.html @@ -1,4 +1,4 @@ -{$layout "layout_popup"} +{$layout "layout_popup"}
-
- -
-
- -
@@ -35,10 +33,10 @@
@@ -47,8 +45,7 @@
- @@ -58,31 +55,44 @@ 暂时还没有运行日志。 - +
- - - - - + - - - - + + - - - -
时间 集群 节点级别类型详情次数信息
{{log.createdTime}}{{log.clusterName}}{{log.nodeName}} - {{log.level}} + + {{log.clusterName}} + + + - + + {{log.nodeName}} + + + - + +
+ + [{{log.createdTime}}] + [{{log.tag}}] + {{log.description}} + + 共{{log.count}}条 +
{{log.tag}}{{log.description}}{{log.count}}
+ \ No newline at end of file diff --git a/EdgeAdmin/web/views/@default/httpdns/runtimeLogs/index.js b/EdgeAdmin/web/views/@default/httpdns/runtimeLogs/index.js index 32f1b41..3047bcc 100644 --- a/EdgeAdmin/web/views/@default/httpdns/runtimeLogs/index.js +++ b/EdgeAdmin/web/views/@default/httpdns/runtimeLogs/index.js @@ -1,4 +1,7 @@ Tea.context(function () { + this.clusterId = ""; + this.nodeId = ""; + this.$delay(function () { teaweb.datepicker("day-from-picker"); teaweb.datepicker("day-to-picker"); diff --git a/EdgeAdmin/web/views/@default/httpdns/sandbox/index.html b/EdgeAdmin/web/views/@default/httpdns/sandbox/index.html index fc69335..09b16b9 100644 --- a/EdgeAdmin/web/views/@default/httpdns/sandbox/index.html +++ b/EdgeAdmin/web/views/@default/httpdns/sandbox/index.html @@ -20,7 +20,7 @@
diff --git a/EdgeAdmin/web/views/@default/httpdns/sandbox/index.js b/EdgeAdmin/web/views/@default/httpdns/sandbox/index.js index 9bf9cf0..0e1ed8a 100644 --- a/EdgeAdmin/web/views/@default/httpdns/sandbox/index.js +++ b/EdgeAdmin/web/views/@default/httpdns/sandbox/index.js @@ -22,6 +22,7 @@ Tea.context(function () { this.isRequesting = false this.currentDomains = [] + this.currentClusters = [] if (typeof this.apps === "undefined") { this.apps = [] @@ -41,6 +42,7 @@ Tea.context(function () { if (selectedApp == null) { this.currentDomains = [] + this.currentClusters = [] this.request.domain = "" this.request.clusterId = "" return @@ -56,8 +58,28 @@ Tea.context(function () { this.request.domain = "" } - if (typeof selectedApp.clusterId !== "undefined" && selectedApp.clusterId !== null) { - this.request.clusterId = String(selectedApp.clusterId) + let primaryClusterId = (typeof selectedApp.primaryClusterId !== "undefined" && selectedApp.primaryClusterId !== null) ? Number(selectedApp.primaryClusterId) : 0 + let backupClusterId = (typeof selectedApp.backupClusterId !== "undefined" && selectedApp.backupClusterId !== null) ? Number(selectedApp.backupClusterId) : 0 + + let allowed = [] + for (let i = 0; i < this.clusters.length; i++) { + let cluster = this.clusters[i] + let clusterId = Number(cluster.id) + if (clusterId <= 0) { + continue + } + if (clusterId === primaryClusterId || clusterId === backupClusterId) { + allowed.push(cluster) + } + } + this.currentClusters = allowed + + if (allowed.length > 0) { + if (!allowed.some((c) => String(c.id) === String(this.request.clusterId))) { + this.request.clusterId = String(allowed[0].id) + } + } else { + this.request.clusterId = "" } } @@ -94,15 +116,15 @@ Tea.context(function () { this.sendTestRequest = function () { if (this.request.appId.length === 0) { - teaweb.warn("Please select target app") + teaweb.warn("请选择目标应用") return } if (this.request.clusterId.length === 0) { - teaweb.warn("Please select cluster") + teaweb.warn("当前应用未绑定可用集群,请先在应用设置中配置主集群/备集群") return } if (this.request.domain.length === 0) { - teaweb.warn("Please select domain") + teaweb.warn("请选择要解析的域名") return } @@ -126,6 +148,7 @@ Tea.context(function () { this.resetForm = function () { this.request = this.newRequest() this.currentDomains = [] + this.currentClusters = [] this.response = { hasResult: false, code: -1, diff --git a/EdgeCommon/pkg/nodeconfigs/node_roles.go b/EdgeCommon/pkg/nodeconfigs/node_roles.go index fab0553..4a46434 100644 --- a/EdgeCommon/pkg/nodeconfigs/node_roles.go +++ b/EdgeCommon/pkg/nodeconfigs/node_roles.go @@ -10,6 +10,7 @@ const ( NodeRoleDatabase NodeRole = "database" NodeRoleLog NodeRole = "log" NodeRoleDNS NodeRole = "dns" + NodeRoleHTTPDNS NodeRole = "httpdns" NodeRoleMonitor NodeRole = "monitor" NodeRoleNode NodeRole = "node" NodeRoleCluster NodeRole = "cluster" diff --git a/EdgeCommon/pkg/rpc/pb/model_httpdns_access_log.pb.go b/EdgeCommon/pkg/rpc/pb/model_httpdns_access_log.pb.go new file mode 100644 index 0000000..f75b0c1 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/model_httpdns_access_log.pb.go @@ -0,0 +1,329 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: models/model_httpdns_access_log.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 HTTPDNSAccessLog struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + RequestId string `protobuf:"bytes,2,opt,name=requestId,proto3" json:"requestId,omitempty"` + ClusterId int64 `protobuf:"varint,3,opt,name=clusterId,proto3" json:"clusterId,omitempty"` + NodeId int64 `protobuf:"varint,4,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + AppId string `protobuf:"bytes,5,opt,name=appId,proto3" json:"appId,omitempty"` + AppName string `protobuf:"bytes,6,opt,name=appName,proto3" json:"appName,omitempty"` + Domain string `protobuf:"bytes,7,opt,name=domain,proto3" json:"domain,omitempty"` + Qtype string `protobuf:"bytes,8,opt,name=qtype,proto3" json:"qtype,omitempty"` + ClientIP string `protobuf:"bytes,9,opt,name=clientIP,proto3" json:"clientIP,omitempty"` + ClientRegion string `protobuf:"bytes,10,opt,name=clientRegion,proto3" json:"clientRegion,omitempty"` + Carrier string `protobuf:"bytes,11,opt,name=carrier,proto3" json:"carrier,omitempty"` + SdkVersion string `protobuf:"bytes,12,opt,name=sdkVersion,proto3" json:"sdkVersion,omitempty"` + Os string `protobuf:"bytes,13,opt,name=os,proto3" json:"os,omitempty"` + ResultIPs string `protobuf:"bytes,14,opt,name=resultIPs,proto3" json:"resultIPs,omitempty"` + Status string `protobuf:"bytes,15,opt,name=status,proto3" json:"status,omitempty"` + ErrorCode string `protobuf:"bytes,16,opt,name=errorCode,proto3" json:"errorCode,omitempty"` + CostMs int32 `protobuf:"varint,17,opt,name=costMs,proto3" json:"costMs,omitempty"` + CreatedAt int64 `protobuf:"varint,18,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + Day string `protobuf:"bytes,19,opt,name=day,proto3" json:"day,omitempty"` + Summary string `protobuf:"bytes,20,opt,name=summary,proto3" json:"summary,omitempty"` + NodeName string `protobuf:"bytes,21,opt,name=nodeName,proto3" json:"nodeName,omitempty"` + ClusterName string `protobuf:"bytes,22,opt,name=clusterName,proto3" json:"clusterName,omitempty"` +} + +func (x *HTTPDNSAccessLog) Reset() { + *x = HTTPDNSAccessLog{} + mi := &file_models_model_httpdns_access_log_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSAccessLog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSAccessLog) ProtoMessage() {} + +func (x *HTTPDNSAccessLog) ProtoReflect() protoreflect.Message { + mi := &file_models_model_httpdns_access_log_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 HTTPDNSAccessLog.ProtoReflect.Descriptor instead. +func (*HTTPDNSAccessLog) Descriptor() ([]byte, []int) { + return file_models_model_httpdns_access_log_proto_rawDescGZIP(), []int{0} +} + +func (x *HTTPDNSAccessLog) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HTTPDNSAccessLog) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *HTTPDNSAccessLog) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +func (x *HTTPDNSAccessLog) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *HTTPDNSAccessLog) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *HTTPDNSAccessLog) GetAppName() string { + if x != nil { + return x.AppName + } + return "" +} + +func (x *HTTPDNSAccessLog) GetDomain() string { + if x != nil { + return x.Domain + } + return "" +} + +func (x *HTTPDNSAccessLog) GetQtype() string { + if x != nil { + return x.Qtype + } + return "" +} + +func (x *HTTPDNSAccessLog) GetClientIP() string { + if x != nil { + return x.ClientIP + } + return "" +} + +func (x *HTTPDNSAccessLog) GetClientRegion() string { + if x != nil { + return x.ClientRegion + } + return "" +} + +func (x *HTTPDNSAccessLog) GetCarrier() string { + if x != nil { + return x.Carrier + } + return "" +} + +func (x *HTTPDNSAccessLog) GetSdkVersion() string { + if x != nil { + return x.SdkVersion + } + return "" +} + +func (x *HTTPDNSAccessLog) GetOs() string { + if x != nil { + return x.Os + } + return "" +} + +func (x *HTTPDNSAccessLog) GetResultIPs() string { + if x != nil { + return x.ResultIPs + } + return "" +} + +func (x *HTTPDNSAccessLog) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *HTTPDNSAccessLog) GetErrorCode() string { + if x != nil { + return x.ErrorCode + } + return "" +} + +func (x *HTTPDNSAccessLog) GetCostMs() int32 { + if x != nil { + return x.CostMs + } + return 0 +} + +func (x *HTTPDNSAccessLog) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *HTTPDNSAccessLog) GetDay() string { + if x != nil { + return x.Day + } + return "" +} + +func (x *HTTPDNSAccessLog) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +func (x *HTTPDNSAccessLog) GetNodeName() string { + if x != nil { + return x.NodeName + } + return "" +} + +func (x *HTTPDNSAccessLog) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +var File_models_model_httpdns_access_log_proto protoreflect.FileDescriptor + +var file_models_model_httpdns_access_log_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, + 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0xd2, 0x04, 0x0a, 0x10, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, + 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, + 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x71, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x12, 0x22, + 0x0a, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, + 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, + 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, + 0x6f, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x1c, 0x0a, 0x09, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x49, 0x50, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x49, 0x50, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x73, 0x74, 0x4d, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x06, 0x63, 0x6f, 0x73, 0x74, 0x4d, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x61, 0x79, 0x18, 0x13, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x61, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x15, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x16, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_models_model_httpdns_access_log_proto_rawDescOnce sync.Once + file_models_model_httpdns_access_log_proto_rawDescData = file_models_model_httpdns_access_log_proto_rawDesc +) + +func file_models_model_httpdns_access_log_proto_rawDescGZIP() []byte { + file_models_model_httpdns_access_log_proto_rawDescOnce.Do(func() { + file_models_model_httpdns_access_log_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_model_httpdns_access_log_proto_rawDescData) + }) + return file_models_model_httpdns_access_log_proto_rawDescData +} + +var file_models_model_httpdns_access_log_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_models_model_httpdns_access_log_proto_goTypes = []any{ + (*HTTPDNSAccessLog)(nil), // 0: pb.HTTPDNSAccessLog +} +var file_models_model_httpdns_access_log_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_models_model_httpdns_access_log_proto_init() } +func file_models_model_httpdns_access_log_proto_init() { + if File_models_model_httpdns_access_log_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_models_model_httpdns_access_log_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_models_model_httpdns_access_log_proto_goTypes, + DependencyIndexes: file_models_model_httpdns_access_log_proto_depIdxs, + MessageInfos: file_models_model_httpdns_access_log_proto_msgTypes, + }.Build() + File_models_model_httpdns_access_log_proto = out.File + file_models_model_httpdns_access_log_proto_rawDesc = nil + file_models_model_httpdns_access_log_proto_goTypes = nil + file_models_model_httpdns_access_log_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/model_httpdns_app.pb.go b/EdgeCommon/pkg/rpc/pb/model_httpdns_app.pb.go new file mode 100644 index 0000000..0d22baf --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/model_httpdns_app.pb.go @@ -0,0 +1,243 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: models/model_httpdns_app.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 HTTPDNSApp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + AppId string `protobuf:"bytes,3,opt,name=appId,proto3" json:"appId,omitempty"` + IsOn bool `protobuf:"varint,4,opt,name=isOn,proto3" json:"isOn,omitempty"` + PrimaryClusterId int64 `protobuf:"varint,5,opt,name=primaryClusterId,proto3" json:"primaryClusterId,omitempty"` + BackupClusterId int64 `protobuf:"varint,6,opt,name=backupClusterId,proto3" json:"backupClusterId,omitempty"` + SniMode string `protobuf:"bytes,7,opt,name=sniMode,proto3" json:"sniMode,omitempty"` + SignEnabled bool `protobuf:"varint,8,opt,name=signEnabled,proto3" json:"signEnabled,omitempty"` + SignSecret string `protobuf:"bytes,9,opt,name=signSecret,proto3" json:"signSecret,omitempty"` + SignUpdatedAt int64 `protobuf:"varint,10,opt,name=signUpdatedAt,proto3" json:"signUpdatedAt,omitempty"` + CreatedAt int64 `protobuf:"varint,11,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt int64 `protobuf:"varint,12,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` + UserId int64 `protobuf:"varint,13,opt,name=userId,proto3" json:"userId,omitempty"` +} + +func (x *HTTPDNSApp) Reset() { + *x = HTTPDNSApp{} + mi := &file_models_model_httpdns_app_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSApp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSApp) ProtoMessage() {} + +func (x *HTTPDNSApp) ProtoReflect() protoreflect.Message { + mi := &file_models_model_httpdns_app_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 HTTPDNSApp.ProtoReflect.Descriptor instead. +func (*HTTPDNSApp) Descriptor() ([]byte, []int) { + return file_models_model_httpdns_app_proto_rawDescGZIP(), []int{0} +} + +func (x *HTTPDNSApp) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HTTPDNSApp) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *HTTPDNSApp) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *HTTPDNSApp) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *HTTPDNSApp) GetPrimaryClusterId() int64 { + if x != nil { + return x.PrimaryClusterId + } + return 0 +} + +func (x *HTTPDNSApp) GetBackupClusterId() int64 { + if x != nil { + return x.BackupClusterId + } + return 0 +} + +func (x *HTTPDNSApp) GetSniMode() string { + if x != nil { + return x.SniMode + } + return "" +} + +func (x *HTTPDNSApp) GetSignEnabled() bool { + if x != nil { + return x.SignEnabled + } + return false +} + +func (x *HTTPDNSApp) GetSignSecret() string { + if x != nil { + return x.SignSecret + } + return "" +} + +func (x *HTTPDNSApp) GetSignUpdatedAt() int64 { + if x != nil { + return x.SignUpdatedAt + } + return 0 +} + +func (x *HTTPDNSApp) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *HTTPDNSApp) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +func (x *HTTPDNSApp) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +var File_models_model_httpdns_app_proto protoreflect.FileDescriptor + +var file_models_model_httpdns_app_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x02, 0x70, 0x62, 0x22, 0xee, 0x02, 0x0a, 0x0a, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x41, 0x70, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, + 0x6e, 0x12, 0x2a, 0x0a, 0x10, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x28, 0x0a, + 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x6e, 0x69, 0x4d, 0x6f, + 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x6e, 0x69, 0x4d, 0x6f, 0x64, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x45, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_models_model_httpdns_app_proto_rawDescOnce sync.Once + file_models_model_httpdns_app_proto_rawDescData = file_models_model_httpdns_app_proto_rawDesc +) + +func file_models_model_httpdns_app_proto_rawDescGZIP() []byte { + file_models_model_httpdns_app_proto_rawDescOnce.Do(func() { + file_models_model_httpdns_app_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_model_httpdns_app_proto_rawDescData) + }) + return file_models_model_httpdns_app_proto_rawDescData +} + +var file_models_model_httpdns_app_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_models_model_httpdns_app_proto_goTypes = []any{ + (*HTTPDNSApp)(nil), // 0: pb.HTTPDNSApp +} +var file_models_model_httpdns_app_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_models_model_httpdns_app_proto_init() } +func file_models_model_httpdns_app_proto_init() { + if File_models_model_httpdns_app_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_models_model_httpdns_app_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_models_model_httpdns_app_proto_goTypes, + DependencyIndexes: file_models_model_httpdns_app_proto_depIdxs, + MessageInfos: file_models_model_httpdns_app_proto_msgTypes, + }.Build() + File_models_model_httpdns_app_proto = out.File + file_models_model_httpdns_app_proto_rawDesc = nil + file_models_model_httpdns_app_proto_goTypes = nil + file_models_model_httpdns_app_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/model_httpdns_cluster.pb.go b/EdgeCommon/pkg/rpc/pb/model_httpdns_cluster.pb.go new file mode 100644 index 0000000..754260d --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/model_httpdns_cluster.pb.go @@ -0,0 +1,226 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: models/model_httpdns_cluster.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 HTTPDNSCluster struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + IsOn bool `protobuf:"varint,2,opt,name=isOn,proto3" json:"isOn,omitempty"` + IsDefault bool `protobuf:"varint,3,opt,name=isDefault,proto3" json:"isDefault,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + ServiceDomain string `protobuf:"bytes,5,opt,name=serviceDomain,proto3" json:"serviceDomain,omitempty"` + DefaultTTL int32 `protobuf:"varint,6,opt,name=defaultTTL,proto3" json:"defaultTTL,omitempty"` + FallbackTimeoutMs int32 `protobuf:"varint,7,opt,name=fallbackTimeoutMs,proto3" json:"fallbackTimeoutMs,omitempty"` + InstallDir string `protobuf:"bytes,8,opt,name=installDir,proto3" json:"installDir,omitempty"` + TlsPolicyJSON []byte `protobuf:"bytes,9,opt,name=tlsPolicyJSON,proto3" json:"tlsPolicyJSON,omitempty"` + CreatedAt int64 `protobuf:"varint,10,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt int64 `protobuf:"varint,11,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` +} + +func (x *HTTPDNSCluster) Reset() { + *x = HTTPDNSCluster{} + mi := &file_models_model_httpdns_cluster_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSCluster) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSCluster) ProtoMessage() {} + +func (x *HTTPDNSCluster) ProtoReflect() protoreflect.Message { + mi := &file_models_model_httpdns_cluster_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 HTTPDNSCluster.ProtoReflect.Descriptor instead. +func (*HTTPDNSCluster) Descriptor() ([]byte, []int) { + return file_models_model_httpdns_cluster_proto_rawDescGZIP(), []int{0} +} + +func (x *HTTPDNSCluster) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HTTPDNSCluster) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *HTTPDNSCluster) GetIsDefault() bool { + if x != nil { + return x.IsDefault + } + return false +} + +func (x *HTTPDNSCluster) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *HTTPDNSCluster) GetServiceDomain() string { + if x != nil { + return x.ServiceDomain + } + return "" +} + +func (x *HTTPDNSCluster) GetDefaultTTL() int32 { + if x != nil { + return x.DefaultTTL + } + return 0 +} + +func (x *HTTPDNSCluster) GetFallbackTimeoutMs() int32 { + if x != nil { + return x.FallbackTimeoutMs + } + return 0 +} + +func (x *HTTPDNSCluster) GetInstallDir() string { + if x != nil { + return x.InstallDir + } + return "" +} + +func (x *HTTPDNSCluster) GetTlsPolicyJSON() []byte { + if x != nil { + return x.TlsPolicyJSON + } + return nil +} + +func (x *HTTPDNSCluster) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *HTTPDNSCluster) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +var File_models_model_httpdns_cluster_proto protoreflect.FileDescriptor + +var file_models_model_httpdns_cluster_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0xdc, 0x02, 0x0a, 0x0e, 0x48, 0x54, 0x54, + 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x69, + 0x73, 0x4f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x12, + 0x1c, 0x0a, 0x09, 0x69, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x54, 0x54, 0x4c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x54, 0x54, 0x4c, 0x12, 0x2c, 0x0a, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x44, 0x69, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6c, 0x73, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x74, 0x6c, + 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4a, 0x53, 0x4f, 0x4e, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_models_model_httpdns_cluster_proto_rawDescOnce sync.Once + file_models_model_httpdns_cluster_proto_rawDescData = file_models_model_httpdns_cluster_proto_rawDesc +) + +func file_models_model_httpdns_cluster_proto_rawDescGZIP() []byte { + file_models_model_httpdns_cluster_proto_rawDescOnce.Do(func() { + file_models_model_httpdns_cluster_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_model_httpdns_cluster_proto_rawDescData) + }) + return file_models_model_httpdns_cluster_proto_rawDescData +} + +var file_models_model_httpdns_cluster_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_models_model_httpdns_cluster_proto_goTypes = []any{ + (*HTTPDNSCluster)(nil), // 0: pb.HTTPDNSCluster +} +var file_models_model_httpdns_cluster_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_models_model_httpdns_cluster_proto_init() } +func file_models_model_httpdns_cluster_proto_init() { + if File_models_model_httpdns_cluster_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_models_model_httpdns_cluster_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_models_model_httpdns_cluster_proto_goTypes, + DependencyIndexes: file_models_model_httpdns_cluster_proto_depIdxs, + MessageInfos: file_models_model_httpdns_cluster_proto_msgTypes, + }.Build() + File_models_model_httpdns_cluster_proto = out.File + file_models_model_httpdns_cluster_proto_rawDesc = nil + file_models_model_httpdns_cluster_proto_goTypes = nil + file_models_model_httpdns_cluster_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/model_httpdns_domain.pb.go b/EdgeCommon/pkg/rpc/pb/model_httpdns_domain.pb.go new file mode 100644 index 0000000..0f2c157 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/model_httpdns_domain.pb.go @@ -0,0 +1,184 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: models/model_httpdns_domain.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 HTTPDNSDomain struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + AppId int64 `protobuf:"varint,2,opt,name=appId,proto3" json:"appId,omitempty"` + Domain string `protobuf:"bytes,3,opt,name=domain,proto3" json:"domain,omitempty"` + IsOn bool `protobuf:"varint,4,opt,name=isOn,proto3" json:"isOn,omitempty"` + CreatedAt int64 `protobuf:"varint,5,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt int64 `protobuf:"varint,6,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` + RuleCount int64 `protobuf:"varint,7,opt,name=ruleCount,proto3" json:"ruleCount,omitempty"` +} + +func (x *HTTPDNSDomain) Reset() { + *x = HTTPDNSDomain{} + mi := &file_models_model_httpdns_domain_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSDomain) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSDomain) ProtoMessage() {} + +func (x *HTTPDNSDomain) ProtoReflect() protoreflect.Message { + mi := &file_models_model_httpdns_domain_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 HTTPDNSDomain.ProtoReflect.Descriptor instead. +func (*HTTPDNSDomain) Descriptor() ([]byte, []int) { + return file_models_model_httpdns_domain_proto_rawDescGZIP(), []int{0} +} + +func (x *HTTPDNSDomain) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HTTPDNSDomain) GetAppId() int64 { + if x != nil { + return x.AppId + } + return 0 +} + +func (x *HTTPDNSDomain) GetDomain() string { + if x != nil { + return x.Domain + } + return "" +} + +func (x *HTTPDNSDomain) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *HTTPDNSDomain) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *HTTPDNSDomain) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +func (x *HTTPDNSDomain) GetRuleCount() int64 { + if x != nil { + return x.RuleCount + } + return 0 +} + +var File_models_model_httpdns_domain_proto protoreflect.FileDescriptor + +var file_models_model_httpdns_domain_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0xbb, 0x01, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, + 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, + 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x75, 0x6c, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x72, 0x75, 0x6c, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_models_model_httpdns_domain_proto_rawDescOnce sync.Once + file_models_model_httpdns_domain_proto_rawDescData = file_models_model_httpdns_domain_proto_rawDesc +) + +func file_models_model_httpdns_domain_proto_rawDescGZIP() []byte { + file_models_model_httpdns_domain_proto_rawDescOnce.Do(func() { + file_models_model_httpdns_domain_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_model_httpdns_domain_proto_rawDescData) + }) + return file_models_model_httpdns_domain_proto_rawDescData +} + +var file_models_model_httpdns_domain_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_models_model_httpdns_domain_proto_goTypes = []any{ + (*HTTPDNSDomain)(nil), // 0: pb.HTTPDNSDomain +} +var file_models_model_httpdns_domain_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_models_model_httpdns_domain_proto_init() } +func file_models_model_httpdns_domain_proto_init() { + if File_models_model_httpdns_domain_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_models_model_httpdns_domain_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_models_model_httpdns_domain_proto_goTypes, + DependencyIndexes: file_models_model_httpdns_domain_proto_depIdxs, + MessageInfos: file_models_model_httpdns_domain_proto_msgTypes, + }.Build() + File_models_model_httpdns_domain_proto = out.File + file_models_model_httpdns_domain_proto_rawDesc = nil + file_models_model_httpdns_domain_proto_goTypes = nil + file_models_model_httpdns_domain_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/model_httpdns_node.pb.go b/EdgeCommon/pkg/rpc/pb/model_httpdns_node.pb.go new file mode 100644 index 0000000..b2f84e2 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/model_httpdns_node.pb.go @@ -0,0 +1,253 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: models/model_httpdns_node.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 HTTPDNSNode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ClusterId int64 `protobuf:"varint,2,opt,name=clusterId,proto3" json:"clusterId,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + IsOn bool `protobuf:"varint,4,opt,name=isOn,proto3" json:"isOn,omitempty"` + IsUp bool `protobuf:"varint,5,opt,name=isUp,proto3" json:"isUp,omitempty"` + IsInstalled bool `protobuf:"varint,6,opt,name=isInstalled,proto3" json:"isInstalled,omitempty"` + IsActive bool `protobuf:"varint,7,opt,name=isActive,proto3" json:"isActive,omitempty"` + UniqueId string `protobuf:"bytes,8,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"` + Secret string `protobuf:"bytes,9,opt,name=secret,proto3" json:"secret,omitempty"` + InstallDir string `protobuf:"bytes,10,opt,name=installDir,proto3" json:"installDir,omitempty"` + StatusJSON []byte `protobuf:"bytes,11,opt,name=statusJSON,proto3" json:"statusJSON,omitempty"` + InstallStatusJSON []byte `protobuf:"bytes,12,opt,name=installStatusJSON,proto3" json:"installStatusJSON,omitempty"` + CreatedAt int64 `protobuf:"varint,13,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + UpdatedAt int64 `protobuf:"varint,14,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` +} + +func (x *HTTPDNSNode) Reset() { + *x = HTTPDNSNode{} + mi := &file_models_model_httpdns_node_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSNode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSNode) ProtoMessage() {} + +func (x *HTTPDNSNode) ProtoReflect() protoreflect.Message { + mi := &file_models_model_httpdns_node_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 HTTPDNSNode.ProtoReflect.Descriptor instead. +func (*HTTPDNSNode) Descriptor() ([]byte, []int) { + return file_models_model_httpdns_node_proto_rawDescGZIP(), []int{0} +} + +func (x *HTTPDNSNode) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HTTPDNSNode) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +func (x *HTTPDNSNode) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *HTTPDNSNode) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *HTTPDNSNode) GetIsUp() bool { + if x != nil { + return x.IsUp + } + return false +} + +func (x *HTTPDNSNode) GetIsInstalled() bool { + if x != nil { + return x.IsInstalled + } + return false +} + +func (x *HTTPDNSNode) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +func (x *HTTPDNSNode) GetUniqueId() string { + if x != nil { + return x.UniqueId + } + return "" +} + +func (x *HTTPDNSNode) GetSecret() string { + if x != nil { + return x.Secret + } + return "" +} + +func (x *HTTPDNSNode) GetInstallDir() string { + if x != nil { + return x.InstallDir + } + return "" +} + +func (x *HTTPDNSNode) GetStatusJSON() []byte { + if x != nil { + return x.StatusJSON + } + return nil +} + +func (x *HTTPDNSNode) GetInstallStatusJSON() []byte { + if x != nil { + return x.InstallStatusJSON + } + return nil +} + +func (x *HTTPDNSNode) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *HTTPDNSNode) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +var File_models_model_httpdns_node_proto protoreflect.FileDescriptor + +var file_models_model_httpdns_node_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x93, 0x03, 0x0a, 0x0b, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x69, + 0x73, 0x55, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x55, 0x70, 0x12, + 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, + 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, + 0x4e, 0x12, 0x2c, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x12, + 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x06, 0x5a, 0x04, 0x2e, + 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_models_model_httpdns_node_proto_rawDescOnce sync.Once + file_models_model_httpdns_node_proto_rawDescData = file_models_model_httpdns_node_proto_rawDesc +) + +func file_models_model_httpdns_node_proto_rawDescGZIP() []byte { + file_models_model_httpdns_node_proto_rawDescOnce.Do(func() { + file_models_model_httpdns_node_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_model_httpdns_node_proto_rawDescData) + }) + return file_models_model_httpdns_node_proto_rawDescData +} + +var file_models_model_httpdns_node_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_models_model_httpdns_node_proto_goTypes = []any{ + (*HTTPDNSNode)(nil), // 0: pb.HTTPDNSNode +} +var file_models_model_httpdns_node_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_models_model_httpdns_node_proto_init() } +func file_models_model_httpdns_node_proto_init() { + if File_models_model_httpdns_node_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_models_model_httpdns_node_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_models_model_httpdns_node_proto_goTypes, + DependencyIndexes: file_models_model_httpdns_node_proto_depIdxs, + MessageInfos: file_models_model_httpdns_node_proto_msgTypes, + }.Build() + File_models_model_httpdns_node_proto = out.File + file_models_model_httpdns_node_proto_rawDesc = nil + file_models_model_httpdns_node_proto_goTypes = nil + file_models_model_httpdns_node_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/model_httpdns_rule.pb.go b/EdgeCommon/pkg/rpc/pb/model_httpdns_rule.pb.go new file mode 100644 index 0000000..7d01941 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/model_httpdns_rule.pb.go @@ -0,0 +1,363 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: models/model_httpdns_rule.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 HTTPDNSRuleRecord struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + RuleId int64 `protobuf:"varint,2,opt,name=ruleId,proto3" json:"ruleId,omitempty"` + RecordType string `protobuf:"bytes,3,opt,name=recordType,proto3" json:"recordType,omitempty"` + RecordValue string `protobuf:"bytes,4,opt,name=recordValue,proto3" json:"recordValue,omitempty"` + Weight int32 `protobuf:"varint,5,opt,name=weight,proto3" json:"weight,omitempty"` + Sort int32 `protobuf:"varint,6,opt,name=sort,proto3" json:"sort,omitempty"` +} + +func (x *HTTPDNSRuleRecord) Reset() { + *x = HTTPDNSRuleRecord{} + mi := &file_models_model_httpdns_rule_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSRuleRecord) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSRuleRecord) ProtoMessage() {} + +func (x *HTTPDNSRuleRecord) ProtoReflect() protoreflect.Message { + mi := &file_models_model_httpdns_rule_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 HTTPDNSRuleRecord.ProtoReflect.Descriptor instead. +func (*HTTPDNSRuleRecord) Descriptor() ([]byte, []int) { + return file_models_model_httpdns_rule_proto_rawDescGZIP(), []int{0} +} + +func (x *HTTPDNSRuleRecord) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HTTPDNSRuleRecord) GetRuleId() int64 { + if x != nil { + return x.RuleId + } + return 0 +} + +func (x *HTTPDNSRuleRecord) GetRecordType() string { + if x != nil { + return x.RecordType + } + return "" +} + +func (x *HTTPDNSRuleRecord) GetRecordValue() string { + if x != nil { + return x.RecordValue + } + return "" +} + +func (x *HTTPDNSRuleRecord) GetWeight() int32 { + if x != nil { + return x.Weight + } + return 0 +} + +func (x *HTTPDNSRuleRecord) GetSort() int32 { + if x != nil { + return x.Sort + } + return 0 +} + +type HTTPDNSCustomRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + AppId int64 `protobuf:"varint,2,opt,name=appId,proto3" json:"appId,omitempty"` + DomainId int64 `protobuf:"varint,3,opt,name=domainId,proto3" json:"domainId,omitempty"` + RuleName string `protobuf:"bytes,4,opt,name=ruleName,proto3" json:"ruleName,omitempty"` + LineScope string `protobuf:"bytes,5,opt,name=lineScope,proto3" json:"lineScope,omitempty"` + LineCarrier string `protobuf:"bytes,6,opt,name=lineCarrier,proto3" json:"lineCarrier,omitempty"` + LineRegion string `protobuf:"bytes,7,opt,name=lineRegion,proto3" json:"lineRegion,omitempty"` + LineProvince string `protobuf:"bytes,8,opt,name=lineProvince,proto3" json:"lineProvince,omitempty"` + LineContinent string `protobuf:"bytes,9,opt,name=lineContinent,proto3" json:"lineContinent,omitempty"` + LineCountry string `protobuf:"bytes,10,opt,name=lineCountry,proto3" json:"lineCountry,omitempty"` + Ttl int32 `protobuf:"varint,11,opt,name=ttl,proto3" json:"ttl,omitempty"` + IsOn bool `protobuf:"varint,12,opt,name=isOn,proto3" json:"isOn,omitempty"` + Priority int32 `protobuf:"varint,13,opt,name=priority,proto3" json:"priority,omitempty"` + UpdatedAt int64 `protobuf:"varint,14,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` + Records []*HTTPDNSRuleRecord `protobuf:"bytes,15,rep,name=records,proto3" json:"records,omitempty"` +} + +func (x *HTTPDNSCustomRule) Reset() { + *x = HTTPDNSCustomRule{} + mi := &file_models_model_httpdns_rule_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSCustomRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSCustomRule) ProtoMessage() {} + +func (x *HTTPDNSCustomRule) ProtoReflect() protoreflect.Message { + mi := &file_models_model_httpdns_rule_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 HTTPDNSCustomRule.ProtoReflect.Descriptor instead. +func (*HTTPDNSCustomRule) Descriptor() ([]byte, []int) { + return file_models_model_httpdns_rule_proto_rawDescGZIP(), []int{1} +} + +func (x *HTTPDNSCustomRule) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HTTPDNSCustomRule) GetAppId() int64 { + if x != nil { + return x.AppId + } + return 0 +} + +func (x *HTTPDNSCustomRule) GetDomainId() int64 { + if x != nil { + return x.DomainId + } + return 0 +} + +func (x *HTTPDNSCustomRule) GetRuleName() string { + if x != nil { + return x.RuleName + } + return "" +} + +func (x *HTTPDNSCustomRule) GetLineScope() string { + if x != nil { + return x.LineScope + } + return "" +} + +func (x *HTTPDNSCustomRule) GetLineCarrier() string { + if x != nil { + return x.LineCarrier + } + return "" +} + +func (x *HTTPDNSCustomRule) GetLineRegion() string { + if x != nil { + return x.LineRegion + } + return "" +} + +func (x *HTTPDNSCustomRule) GetLineProvince() string { + if x != nil { + return x.LineProvince + } + return "" +} + +func (x *HTTPDNSCustomRule) GetLineContinent() string { + if x != nil { + return x.LineContinent + } + return "" +} + +func (x *HTTPDNSCustomRule) GetLineCountry() string { + if x != nil { + return x.LineCountry + } + return "" +} + +func (x *HTTPDNSCustomRule) GetTtl() int32 { + if x != nil { + return x.Ttl + } + return 0 +} + +func (x *HTTPDNSCustomRule) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *HTTPDNSCustomRule) GetPriority() int32 { + if x != nil { + return x.Priority + } + return 0 +} + +func (x *HTTPDNSCustomRule) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +func (x *HTTPDNSCustomRule) GetRecords() []*HTTPDNSRuleRecord { + if x != nil { + return x.Records + } + return nil +} + +var File_models_model_httpdns_rule_proto protoreflect.FileDescriptor + +var file_models_model_httpdns_rule_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0xa9, 0x01, 0x0a, 0x11, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x75, 0x6c, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x75, 0x6c, + 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x6f, 0x72, + 0x74, 0x22, 0xce, 0x03, 0x0a, 0x11, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x08, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x75, 0x6c, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x75, 0x6c, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x63, 0x6f, + 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x63, + 0x6f, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x61, 0x72, 0x72, 0x69, + 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x61, + 0x72, 0x72, 0x69, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x52, + 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x69, 0x6e, + 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x69, 0x6e, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x12, + 0x20, 0x0a, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, + 0x74, 0x74, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x2f, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x0f, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, + 0x64, 0x73, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_models_model_httpdns_rule_proto_rawDescOnce sync.Once + file_models_model_httpdns_rule_proto_rawDescData = file_models_model_httpdns_rule_proto_rawDesc +) + +func file_models_model_httpdns_rule_proto_rawDescGZIP() []byte { + file_models_model_httpdns_rule_proto_rawDescOnce.Do(func() { + file_models_model_httpdns_rule_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_model_httpdns_rule_proto_rawDescData) + }) + return file_models_model_httpdns_rule_proto_rawDescData +} + +var file_models_model_httpdns_rule_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_models_model_httpdns_rule_proto_goTypes = []any{ + (*HTTPDNSRuleRecord)(nil), // 0: pb.HTTPDNSRuleRecord + (*HTTPDNSCustomRule)(nil), // 1: pb.HTTPDNSCustomRule +} +var file_models_model_httpdns_rule_proto_depIdxs = []int32{ + 0, // 0: pb.HTTPDNSCustomRule.records:type_name -> pb.HTTPDNSRuleRecord + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_models_model_httpdns_rule_proto_init() } +func file_models_model_httpdns_rule_proto_init() { + if File_models_model_httpdns_rule_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_models_model_httpdns_rule_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_models_model_httpdns_rule_proto_goTypes, + DependencyIndexes: file_models_model_httpdns_rule_proto_depIdxs, + MessageInfos: file_models_model_httpdns_rule_proto_msgTypes, + }.Build() + File_models_model_httpdns_rule_proto = out.File + file_models_model_httpdns_rule_proto_rawDesc = nil + file_models_model_httpdns_rule_proto_goTypes = nil + file_models_model_httpdns_rule_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/model_httpdns_runtime_log.pb.go b/EdgeCommon/pkg/rpc/pb/model_httpdns_runtime_log.pb.go new file mode 100644 index 0000000..e408505 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/model_httpdns_runtime_log.pb.go @@ -0,0 +1,242 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: models/model_httpdns_runtime_log.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 HTTPDNSRuntimeLog struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ClusterId int64 `protobuf:"varint,2,opt,name=clusterId,proto3" json:"clusterId,omitempty"` + NodeId int64 `protobuf:"varint,3,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + Level string `protobuf:"bytes,4,opt,name=level,proto3" json:"level,omitempty"` + Type string `protobuf:"bytes,5,opt,name=type,proto3" json:"type,omitempty"` + Module string `protobuf:"bytes,6,opt,name=module,proto3" json:"module,omitempty"` + Description string `protobuf:"bytes,7,opt,name=description,proto3" json:"description,omitempty"` + Count int64 `protobuf:"varint,8,opt,name=count,proto3" json:"count,omitempty"` + RequestId string `protobuf:"bytes,9,opt,name=requestId,proto3" json:"requestId,omitempty"` + CreatedAt int64 `protobuf:"varint,10,opt,name=createdAt,proto3" json:"createdAt,omitempty"` + Day string `protobuf:"bytes,11,opt,name=day,proto3" json:"day,omitempty"` + ClusterName string `protobuf:"bytes,12,opt,name=clusterName,proto3" json:"clusterName,omitempty"` + NodeName string `protobuf:"bytes,13,opt,name=nodeName,proto3" json:"nodeName,omitempty"` +} + +func (x *HTTPDNSRuntimeLog) Reset() { + *x = HTTPDNSRuntimeLog{} + mi := &file_models_model_httpdns_runtime_log_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSRuntimeLog) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSRuntimeLog) ProtoMessage() {} + +func (x *HTTPDNSRuntimeLog) ProtoReflect() protoreflect.Message { + mi := &file_models_model_httpdns_runtime_log_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 HTTPDNSRuntimeLog.ProtoReflect.Descriptor instead. +func (*HTTPDNSRuntimeLog) Descriptor() ([]byte, []int) { + return file_models_model_httpdns_runtime_log_proto_rawDescGZIP(), []int{0} +} + +func (x *HTTPDNSRuntimeLog) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *HTTPDNSRuntimeLog) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +func (x *HTTPDNSRuntimeLog) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *HTTPDNSRuntimeLog) GetLevel() string { + if x != nil { + return x.Level + } + return "" +} + +func (x *HTTPDNSRuntimeLog) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *HTTPDNSRuntimeLog) GetModule() string { + if x != nil { + return x.Module + } + return "" +} + +func (x *HTTPDNSRuntimeLog) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *HTTPDNSRuntimeLog) GetCount() int64 { + if x != nil { + return x.Count + } + return 0 +} + +func (x *HTTPDNSRuntimeLog) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *HTTPDNSRuntimeLog) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *HTTPDNSRuntimeLog) GetDay() string { + if x != nil { + return x.Day + } + return "" +} + +func (x *HTTPDNSRuntimeLog) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +func (x *HTTPDNSRuntimeLog) GetNodeName() string { + if x != nil { + return x.NodeName + } + return "" +} + +var File_models_model_httpdns_runtime_log_proto protoreflect.FileDescriptor + +var file_models_model_httpdns_runtime_log_proto_rawDesc = []byte{ + 0x0a, 0x26, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6c, + 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0xdf, 0x02, 0x0a, + 0x11, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, + 0x6f, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, + 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, + 0x0a, 0x03, 0x64, 0x61, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x61, 0x79, + 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x06, + 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_models_model_httpdns_runtime_log_proto_rawDescOnce sync.Once + file_models_model_httpdns_runtime_log_proto_rawDescData = file_models_model_httpdns_runtime_log_proto_rawDesc +) + +func file_models_model_httpdns_runtime_log_proto_rawDescGZIP() []byte { + file_models_model_httpdns_runtime_log_proto_rawDescOnce.Do(func() { + file_models_model_httpdns_runtime_log_proto_rawDescData = protoimpl.X.CompressGZIP(file_models_model_httpdns_runtime_log_proto_rawDescData) + }) + return file_models_model_httpdns_runtime_log_proto_rawDescData +} + +var file_models_model_httpdns_runtime_log_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_models_model_httpdns_runtime_log_proto_goTypes = []any{ + (*HTTPDNSRuntimeLog)(nil), // 0: pb.HTTPDNSRuntimeLog +} +var file_models_model_httpdns_runtime_log_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_models_model_httpdns_runtime_log_proto_init() } +func file_models_model_httpdns_runtime_log_proto_init() { + if File_models_model_httpdns_runtime_log_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_models_model_httpdns_runtime_log_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_models_model_httpdns_runtime_log_proto_goTypes, + DependencyIndexes: file_models_model_httpdns_runtime_log_proto_depIdxs, + MessageInfos: file_models_model_httpdns_runtime_log_proto_msgTypes, + }.Build() + File_models_model_httpdns_runtime_log_proto = out.File + file_models_model_httpdns_runtime_log_proto_rawDesc = nil + file_models_model_httpdns_runtime_log_proto_goTypes = nil + file_models_model_httpdns_runtime_log_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_access_log.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_access_log.pb.go new file mode 100644 index 0000000..291a198 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_access_log.pb.go @@ -0,0 +1,377 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: service_httpdns_access_log.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 CreateHTTPDNSAccessLogsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Logs []*HTTPDNSAccessLog `protobuf:"bytes,1,rep,name=logs,proto3" json:"logs,omitempty"` +} + +func (x *CreateHTTPDNSAccessLogsRequest) Reset() { + *x = CreateHTTPDNSAccessLogsRequest{} + mi := &file_service_httpdns_access_log_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSAccessLogsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSAccessLogsRequest) ProtoMessage() {} + +func (x *CreateHTTPDNSAccessLogsRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_access_log_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 CreateHTTPDNSAccessLogsRequest.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSAccessLogsRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_access_log_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateHTTPDNSAccessLogsRequest) GetLogs() []*HTTPDNSAccessLog { + if x != nil { + return x.Logs + } + return nil +} + +type CreateHTTPDNSAccessLogsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *CreateHTTPDNSAccessLogsResponse) Reset() { + *x = CreateHTTPDNSAccessLogsResponse{} + mi := &file_service_httpdns_access_log_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSAccessLogsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSAccessLogsResponse) ProtoMessage() {} + +func (x *CreateHTTPDNSAccessLogsResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_access_log_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 CreateHTTPDNSAccessLogsResponse.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSAccessLogsResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_access_log_proto_rawDescGZIP(), []int{1} +} + +type ListHTTPDNSAccessLogsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Day string `protobuf:"bytes,1,opt,name=day,proto3" json:"day,omitempty"` + ClusterId int64 `protobuf:"varint,2,opt,name=clusterId,proto3" json:"clusterId,omitempty"` + NodeId int64 `protobuf:"varint,3,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + AppId string `protobuf:"bytes,4,opt,name=appId,proto3" json:"appId,omitempty"` + Domain string `protobuf:"bytes,5,opt,name=domain,proto3" json:"domain,omitempty"` + Status string `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"` + Keyword string `protobuf:"bytes,7,opt,name=keyword,proto3" json:"keyword,omitempty"` + Offset int64 `protobuf:"varint,8,opt,name=offset,proto3" json:"offset,omitempty"` + Size int64 `protobuf:"varint,9,opt,name=size,proto3" json:"size,omitempty"` +} + +func (x *ListHTTPDNSAccessLogsRequest) Reset() { + *x = ListHTTPDNSAccessLogsRequest{} + mi := &file_service_httpdns_access_log_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSAccessLogsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSAccessLogsRequest) ProtoMessage() {} + +func (x *ListHTTPDNSAccessLogsRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_access_log_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 ListHTTPDNSAccessLogsRequest.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSAccessLogsRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_access_log_proto_rawDescGZIP(), []int{2} +} + +func (x *ListHTTPDNSAccessLogsRequest) GetDay() string { + if x != nil { + return x.Day + } + return "" +} + +func (x *ListHTTPDNSAccessLogsRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +func (x *ListHTTPDNSAccessLogsRequest) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *ListHTTPDNSAccessLogsRequest) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *ListHTTPDNSAccessLogsRequest) GetDomain() string { + if x != nil { + return x.Domain + } + return "" +} + +func (x *ListHTTPDNSAccessLogsRequest) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *ListHTTPDNSAccessLogsRequest) GetKeyword() string { + if x != nil { + return x.Keyword + } + return "" +} + +func (x *ListHTTPDNSAccessLogsRequest) GetOffset() int64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListHTTPDNSAccessLogsRequest) GetSize() int64 { + if x != nil { + return x.Size + } + return 0 +} + +type ListHTTPDNSAccessLogsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Logs []*HTTPDNSAccessLog `protobuf:"bytes,1,rep,name=logs,proto3" json:"logs,omitempty"` + Total int64 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` +} + +func (x *ListHTTPDNSAccessLogsResponse) Reset() { + *x = ListHTTPDNSAccessLogsResponse{} + mi := &file_service_httpdns_access_log_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSAccessLogsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSAccessLogsResponse) ProtoMessage() {} + +func (x *ListHTTPDNSAccessLogsResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_access_log_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 ListHTTPDNSAccessLogsResponse.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSAccessLogsResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_access_log_proto_rawDescGZIP(), []int{3} +} + +func (x *ListHTTPDNSAccessLogsResponse) GetLogs() []*HTTPDNSAccessLog { + if x != nil { + return x.Logs + } + return nil +} + +func (x *ListHTTPDNSAccessLogsResponse) GetTotal() int64 { + if x != nil { + return x.Total + } + return 0 +} + +var File_service_httpdns_access_log_proto protoreflect.FileDescriptor + +var file_service_httpdns_access_log_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, + 0x73, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x25, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4a, 0x0a, + 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x28, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x21, 0x0a, 0x1f, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf2, 0x01, 0x0a, + 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x64, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x61, 0x79, 0x12, + 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, + 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6b, + 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, + 0x79, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x22, 0x5f, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x32, 0xdb, 0x01, 0x0a, 0x17, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, + 0x0a, 0x17, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x22, 0x2e, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, + 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x20, 0x2e, 0x70, 0x62, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_service_httpdns_access_log_proto_rawDescOnce sync.Once + file_service_httpdns_access_log_proto_rawDescData = file_service_httpdns_access_log_proto_rawDesc +) + +func file_service_httpdns_access_log_proto_rawDescGZIP() []byte { + file_service_httpdns_access_log_proto_rawDescOnce.Do(func() { + file_service_httpdns_access_log_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_httpdns_access_log_proto_rawDescData) + }) + return file_service_httpdns_access_log_proto_rawDescData +} + +var file_service_httpdns_access_log_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_service_httpdns_access_log_proto_goTypes = []any{ + (*CreateHTTPDNSAccessLogsRequest)(nil), // 0: pb.CreateHTTPDNSAccessLogsRequest + (*CreateHTTPDNSAccessLogsResponse)(nil), // 1: pb.CreateHTTPDNSAccessLogsResponse + (*ListHTTPDNSAccessLogsRequest)(nil), // 2: pb.ListHTTPDNSAccessLogsRequest + (*ListHTTPDNSAccessLogsResponse)(nil), // 3: pb.ListHTTPDNSAccessLogsResponse + (*HTTPDNSAccessLog)(nil), // 4: pb.HTTPDNSAccessLog +} +var file_service_httpdns_access_log_proto_depIdxs = []int32{ + 4, // 0: pb.CreateHTTPDNSAccessLogsRequest.logs:type_name -> pb.HTTPDNSAccessLog + 4, // 1: pb.ListHTTPDNSAccessLogsResponse.logs:type_name -> pb.HTTPDNSAccessLog + 0, // 2: pb.HTTPDNSAccessLogService.createHTTPDNSAccessLogs:input_type -> pb.CreateHTTPDNSAccessLogsRequest + 2, // 3: pb.HTTPDNSAccessLogService.listHTTPDNSAccessLogs:input_type -> pb.ListHTTPDNSAccessLogsRequest + 1, // 4: pb.HTTPDNSAccessLogService.createHTTPDNSAccessLogs:output_type -> pb.CreateHTTPDNSAccessLogsResponse + 3, // 5: pb.HTTPDNSAccessLogService.listHTTPDNSAccessLogs:output_type -> pb.ListHTTPDNSAccessLogsResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_service_httpdns_access_log_proto_init() } +func file_service_httpdns_access_log_proto_init() { + if File_service_httpdns_access_log_proto != nil { + return + } + file_models_model_httpdns_access_log_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_service_httpdns_access_log_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_service_httpdns_access_log_proto_goTypes, + DependencyIndexes: file_service_httpdns_access_log_proto_depIdxs, + MessageInfos: file_service_httpdns_access_log_proto_msgTypes, + }.Build() + File_service_httpdns_access_log_proto = out.File + file_service_httpdns_access_log_proto_rawDesc = nil + file_service_httpdns_access_log_proto_goTypes = nil + file_service_httpdns_access_log_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_access_log_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_access_log_grpc.pb.go new file mode 100644 index 0000000..72f8c12 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_access_log_grpc.pb.go @@ -0,0 +1,157 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: service_httpdns_access_log.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 ( + HTTPDNSAccessLogService_CreateHTTPDNSAccessLogs_FullMethodName = "/pb.HTTPDNSAccessLogService/createHTTPDNSAccessLogs" + HTTPDNSAccessLogService_ListHTTPDNSAccessLogs_FullMethodName = "/pb.HTTPDNSAccessLogService/listHTTPDNSAccessLogs" +) + +// HTTPDNSAccessLogServiceClient is the client API for HTTPDNSAccessLogService 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. +type HTTPDNSAccessLogServiceClient interface { + CreateHTTPDNSAccessLogs(ctx context.Context, in *CreateHTTPDNSAccessLogsRequest, opts ...grpc.CallOption) (*CreateHTTPDNSAccessLogsResponse, error) + ListHTTPDNSAccessLogs(ctx context.Context, in *ListHTTPDNSAccessLogsRequest, opts ...grpc.CallOption) (*ListHTTPDNSAccessLogsResponse, error) +} + +type hTTPDNSAccessLogServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHTTPDNSAccessLogServiceClient(cc grpc.ClientConnInterface) HTTPDNSAccessLogServiceClient { + return &hTTPDNSAccessLogServiceClient{cc} +} + +func (c *hTTPDNSAccessLogServiceClient) CreateHTTPDNSAccessLogs(ctx context.Context, in *CreateHTTPDNSAccessLogsRequest, opts ...grpc.CallOption) (*CreateHTTPDNSAccessLogsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateHTTPDNSAccessLogsResponse) + err := c.cc.Invoke(ctx, HTTPDNSAccessLogService_CreateHTTPDNSAccessLogs_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSAccessLogServiceClient) ListHTTPDNSAccessLogs(ctx context.Context, in *ListHTTPDNSAccessLogsRequest, opts ...grpc.CallOption) (*ListHTTPDNSAccessLogsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListHTTPDNSAccessLogsResponse) + err := c.cc.Invoke(ctx, HTTPDNSAccessLogService_ListHTTPDNSAccessLogs_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HTTPDNSAccessLogServiceServer is the server API for HTTPDNSAccessLogService service. +// All implementations should embed UnimplementedHTTPDNSAccessLogServiceServer +// for forward compatibility. +type HTTPDNSAccessLogServiceServer interface { + CreateHTTPDNSAccessLogs(context.Context, *CreateHTTPDNSAccessLogsRequest) (*CreateHTTPDNSAccessLogsResponse, error) + ListHTTPDNSAccessLogs(context.Context, *ListHTTPDNSAccessLogsRequest) (*ListHTTPDNSAccessLogsResponse, error) +} + +// UnimplementedHTTPDNSAccessLogServiceServer 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 UnimplementedHTTPDNSAccessLogServiceServer struct{} + +func (UnimplementedHTTPDNSAccessLogServiceServer) CreateHTTPDNSAccessLogs(context.Context, *CreateHTTPDNSAccessLogsRequest) (*CreateHTTPDNSAccessLogsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHTTPDNSAccessLogs not implemented") +} +func (UnimplementedHTTPDNSAccessLogServiceServer) ListHTTPDNSAccessLogs(context.Context, *ListHTTPDNSAccessLogsRequest) (*ListHTTPDNSAccessLogsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListHTTPDNSAccessLogs not implemented") +} +func (UnimplementedHTTPDNSAccessLogServiceServer) testEmbeddedByValue() {} + +// UnsafeHTTPDNSAccessLogServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HTTPDNSAccessLogServiceServer will +// result in compilation errors. +type UnsafeHTTPDNSAccessLogServiceServer interface { + mustEmbedUnimplementedHTTPDNSAccessLogServiceServer() +} + +func RegisterHTTPDNSAccessLogServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSAccessLogServiceServer) { + // If the following call pancis, it indicates UnimplementedHTTPDNSAccessLogServiceServer 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(&HTTPDNSAccessLogService_ServiceDesc, srv) +} + +func _HTTPDNSAccessLogService_CreateHTTPDNSAccessLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateHTTPDNSAccessLogsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAccessLogServiceServer).CreateHTTPDNSAccessLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAccessLogService_CreateHTTPDNSAccessLogs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAccessLogServiceServer).CreateHTTPDNSAccessLogs(ctx, req.(*CreateHTTPDNSAccessLogsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSAccessLogService_ListHTTPDNSAccessLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListHTTPDNSAccessLogsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAccessLogServiceServer).ListHTTPDNSAccessLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAccessLogService_ListHTTPDNSAccessLogs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAccessLogServiceServer).ListHTTPDNSAccessLogs(ctx, req.(*ListHTTPDNSAccessLogsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HTTPDNSAccessLogService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSAccessLogService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HTTPDNSAccessLogService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.HTTPDNSAccessLogService", + HandlerType: (*HTTPDNSAccessLogServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "createHTTPDNSAccessLogs", + Handler: _HTTPDNSAccessLogService_CreateHTTPDNSAccessLogs_Handler, + }, + { + MethodName: "listHTTPDNSAccessLogs", + Handler: _HTTPDNSAccessLogService_ListHTTPDNSAccessLogs_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service_httpdns_access_log.proto", +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_app.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_app.pb.go new file mode 100644 index 0000000..4ce3123 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_app.pb.go @@ -0,0 +1,924 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: service_httpdns_app.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 CreateHTTPDNSAppRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + AppId string `protobuf:"bytes,2,opt,name=appId,proto3" json:"appId,omitempty"` + PrimaryClusterId int64 `protobuf:"varint,3,opt,name=primaryClusterId,proto3" json:"primaryClusterId,omitempty"` + BackupClusterId int64 `protobuf:"varint,4,opt,name=backupClusterId,proto3" json:"backupClusterId,omitempty"` + IsOn bool `protobuf:"varint,5,opt,name=isOn,proto3" json:"isOn,omitempty"` + SignEnabled bool `protobuf:"varint,6,opt,name=signEnabled,proto3" json:"signEnabled,omitempty"` + UserId int64 `protobuf:"varint,7,opt,name=userId,proto3" json:"userId,omitempty"` +} + +func (x *CreateHTTPDNSAppRequest) Reset() { + *x = CreateHTTPDNSAppRequest{} + mi := &file_service_httpdns_app_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSAppRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSAppRequest) ProtoMessage() {} + +func (x *CreateHTTPDNSAppRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_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 CreateHTTPDNSAppRequest.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSAppRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateHTTPDNSAppRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateHTTPDNSAppRequest) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *CreateHTTPDNSAppRequest) GetPrimaryClusterId() int64 { + if x != nil { + return x.PrimaryClusterId + } + return 0 +} + +func (x *CreateHTTPDNSAppRequest) GetBackupClusterId() int64 { + if x != nil { + return x.BackupClusterId + } + return 0 +} + +func (x *CreateHTTPDNSAppRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *CreateHTTPDNSAppRequest) GetSignEnabled() bool { + if x != nil { + return x.SignEnabled + } + return false +} + +func (x *CreateHTTPDNSAppRequest) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +type CreateHTTPDNSAppResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppDbId int64 `protobuf:"varint,1,opt,name=appDbId,proto3" json:"appDbId,omitempty"` +} + +func (x *CreateHTTPDNSAppResponse) Reset() { + *x = CreateHTTPDNSAppResponse{} + mi := &file_service_httpdns_app_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSAppResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSAppResponse) ProtoMessage() {} + +func (x *CreateHTTPDNSAppResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_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 CreateHTTPDNSAppResponse.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSAppResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateHTTPDNSAppResponse) GetAppDbId() int64 { + if x != nil { + return x.AppDbId + } + return 0 +} + +type UpdateHTTPDNSAppRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppDbId int64 `protobuf:"varint,1,opt,name=appDbId,proto3" json:"appDbId,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + PrimaryClusterId int64 `protobuf:"varint,3,opt,name=primaryClusterId,proto3" json:"primaryClusterId,omitempty"` + BackupClusterId int64 `protobuf:"varint,4,opt,name=backupClusterId,proto3" json:"backupClusterId,omitempty"` + IsOn bool `protobuf:"varint,5,opt,name=isOn,proto3" json:"isOn,omitempty"` + UserId int64 `protobuf:"varint,6,opt,name=userId,proto3" json:"userId,omitempty"` +} + +func (x *UpdateHTTPDNSAppRequest) Reset() { + *x = UpdateHTTPDNSAppRequest{} + mi := &file_service_httpdns_app_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSAppRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSAppRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSAppRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_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 UpdateHTTPDNSAppRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSAppRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateHTTPDNSAppRequest) GetAppDbId() int64 { + if x != nil { + return x.AppDbId + } + return 0 +} + +func (x *UpdateHTTPDNSAppRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateHTTPDNSAppRequest) GetPrimaryClusterId() int64 { + if x != nil { + return x.PrimaryClusterId + } + return 0 +} + +func (x *UpdateHTTPDNSAppRequest) GetBackupClusterId() int64 { + if x != nil { + return x.BackupClusterId + } + return 0 +} + +func (x *UpdateHTTPDNSAppRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *UpdateHTTPDNSAppRequest) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +type DeleteHTTPDNSAppRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppDbId int64 `protobuf:"varint,1,opt,name=appDbId,proto3" json:"appDbId,omitempty"` +} + +func (x *DeleteHTTPDNSAppRequest) Reset() { + *x = DeleteHTTPDNSAppRequest{} + mi := &file_service_httpdns_app_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteHTTPDNSAppRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteHTTPDNSAppRequest) ProtoMessage() {} + +func (x *DeleteHTTPDNSAppRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_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 DeleteHTTPDNSAppRequest.ProtoReflect.Descriptor instead. +func (*DeleteHTTPDNSAppRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{3} +} + +func (x *DeleteHTTPDNSAppRequest) GetAppDbId() int64 { + if x != nil { + return x.AppDbId + } + return 0 +} + +type FindHTTPDNSAppRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppDbId int64 `protobuf:"varint,1,opt,name=appDbId,proto3" json:"appDbId,omitempty"` +} + +func (x *FindHTTPDNSAppRequest) Reset() { + *x = FindHTTPDNSAppRequest{} + mi := &file_service_httpdns_app_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindHTTPDNSAppRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindHTTPDNSAppRequest) ProtoMessage() {} + +func (x *FindHTTPDNSAppRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_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 FindHTTPDNSAppRequest.ProtoReflect.Descriptor instead. +func (*FindHTTPDNSAppRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{4} +} + +func (x *FindHTTPDNSAppRequest) GetAppDbId() int64 { + if x != nil { + return x.AppDbId + } + return 0 +} + +type FindHTTPDNSAppResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + App *HTTPDNSApp `protobuf:"bytes,1,opt,name=app,proto3" json:"app,omitempty"` +} + +func (x *FindHTTPDNSAppResponse) Reset() { + *x = FindHTTPDNSAppResponse{} + mi := &file_service_httpdns_app_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindHTTPDNSAppResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindHTTPDNSAppResponse) ProtoMessage() {} + +func (x *FindHTTPDNSAppResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_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 FindHTTPDNSAppResponse.ProtoReflect.Descriptor instead. +func (*FindHTTPDNSAppResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{5} +} + +func (x *FindHTTPDNSAppResponse) GetApp() *HTTPDNSApp { + if x != nil { + return x.App + } + return nil +} + +type ListHTTPDNSAppsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Offset int64 `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"` + Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + Keyword string `protobuf:"bytes,3,opt,name=keyword,proto3" json:"keyword,omitempty"` +} + +func (x *ListHTTPDNSAppsRequest) Reset() { + *x = ListHTTPDNSAppsRequest{} + mi := &file_service_httpdns_app_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSAppsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSAppsRequest) ProtoMessage() {} + +func (x *ListHTTPDNSAppsRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_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 ListHTTPDNSAppsRequest.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSAppsRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{6} +} + +func (x *ListHTTPDNSAppsRequest) GetOffset() int64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListHTTPDNSAppsRequest) GetSize() int64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ListHTTPDNSAppsRequest) GetKeyword() string { + if x != nil { + return x.Keyword + } + return "" +} + +type ListHTTPDNSAppsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Apps []*HTTPDNSApp `protobuf:"bytes,1,rep,name=apps,proto3" json:"apps,omitempty"` +} + +func (x *ListHTTPDNSAppsResponse) Reset() { + *x = ListHTTPDNSAppsResponse{} + mi := &file_service_httpdns_app_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSAppsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSAppsResponse) ProtoMessage() {} + +func (x *ListHTTPDNSAppsResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_proto_msgTypes[7] + 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 ListHTTPDNSAppsResponse.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSAppsResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{7} +} + +func (x *ListHTTPDNSAppsResponse) GetApps() []*HTTPDNSApp { + if x != nil { + return x.Apps + } + return nil +} + +type FindAllHTTPDNSAppsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FindAllHTTPDNSAppsRequest) Reset() { + *x = FindAllHTTPDNSAppsRequest{} + mi := &file_service_httpdns_app_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindAllHTTPDNSAppsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindAllHTTPDNSAppsRequest) ProtoMessage() {} + +func (x *FindAllHTTPDNSAppsRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_proto_msgTypes[8] + 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 FindAllHTTPDNSAppsRequest.ProtoReflect.Descriptor instead. +func (*FindAllHTTPDNSAppsRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{8} +} + +type FindAllHTTPDNSAppsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Apps []*HTTPDNSApp `protobuf:"bytes,1,rep,name=apps,proto3" json:"apps,omitempty"` +} + +func (x *FindAllHTTPDNSAppsResponse) Reset() { + *x = FindAllHTTPDNSAppsResponse{} + mi := &file_service_httpdns_app_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindAllHTTPDNSAppsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindAllHTTPDNSAppsResponse) ProtoMessage() {} + +func (x *FindAllHTTPDNSAppsResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_proto_msgTypes[9] + 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 FindAllHTTPDNSAppsResponse.ProtoReflect.Descriptor instead. +func (*FindAllHTTPDNSAppsResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{9} +} + +func (x *FindAllHTTPDNSAppsResponse) GetApps() []*HTTPDNSApp { + if x != nil { + return x.Apps + } + return nil +} + +type UpdateHTTPDNSAppSignEnabledRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppDbId int64 `protobuf:"varint,1,opt,name=appDbId,proto3" json:"appDbId,omitempty"` + SignEnabled bool `protobuf:"varint,2,opt,name=signEnabled,proto3" json:"signEnabled,omitempty"` +} + +func (x *UpdateHTTPDNSAppSignEnabledRequest) Reset() { + *x = UpdateHTTPDNSAppSignEnabledRequest{} + mi := &file_service_httpdns_app_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSAppSignEnabledRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSAppSignEnabledRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSAppSignEnabledRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_proto_msgTypes[10] + 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 UpdateHTTPDNSAppSignEnabledRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSAppSignEnabledRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{10} +} + +func (x *UpdateHTTPDNSAppSignEnabledRequest) GetAppDbId() int64 { + if x != nil { + return x.AppDbId + } + return 0 +} + +func (x *UpdateHTTPDNSAppSignEnabledRequest) GetSignEnabled() bool { + if x != nil { + return x.SignEnabled + } + return false +} + +type ResetHTTPDNSAppSignSecretRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppDbId int64 `protobuf:"varint,1,opt,name=appDbId,proto3" json:"appDbId,omitempty"` +} + +func (x *ResetHTTPDNSAppSignSecretRequest) Reset() { + *x = ResetHTTPDNSAppSignSecretRequest{} + mi := &file_service_httpdns_app_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResetHTTPDNSAppSignSecretRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetHTTPDNSAppSignSecretRequest) ProtoMessage() {} + +func (x *ResetHTTPDNSAppSignSecretRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_proto_msgTypes[11] + 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 ResetHTTPDNSAppSignSecretRequest.ProtoReflect.Descriptor instead. +func (*ResetHTTPDNSAppSignSecretRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{11} +} + +func (x *ResetHTTPDNSAppSignSecretRequest) GetAppDbId() int64 { + if x != nil { + return x.AppDbId + } + return 0 +} + +type ResetHTTPDNSAppSignSecretResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SignSecret string `protobuf:"bytes,1,opt,name=signSecret,proto3" json:"signSecret,omitempty"` + UpdatedAt int64 `protobuf:"varint,2,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"` +} + +func (x *ResetHTTPDNSAppSignSecretResponse) Reset() { + *x = ResetHTTPDNSAppSignSecretResponse{} + mi := &file_service_httpdns_app_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResetHTTPDNSAppSignSecretResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetHTTPDNSAppSignSecretResponse) ProtoMessage() {} + +func (x *ResetHTTPDNSAppSignSecretResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_app_proto_msgTypes[12] + 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 ResetHTTPDNSAppSignSecretResponse.ProtoReflect.Descriptor instead. +func (*ResetHTTPDNSAppSignSecretResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_app_proto_rawDescGZIP(), []int{12} +} + +func (x *ResetHTTPDNSAppSignSecretResponse) GetSignSecret() string { + if x != nil { + return x.SignSecret + } + return "" +} + +func (x *ResetHTTPDNSAppSignSecretResponse) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +var File_service_httpdns_app_proto protoreflect.FileDescriptor + +var file_service_httpdns_app_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, + 0x73, 0x5f, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, + 0x1e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, 0x74, + 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x19, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcf, 0x01, 0x0a, 0x17, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, + 0x70, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, + 0x12, 0x2a, 0x0a, 0x10, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x69, + 0x67, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x34, 0x0a, 0x18, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x44, + 0x62, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, + 0x49, 0x64, 0x22, 0xb1, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, + 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x22, 0x33, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x22, 0x31, 0x0a, 0x15, 0x46, + 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x22, 0x3a, + 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x03, 0x61, 0x70, 0x70, 0x22, 0x5e, 0x0a, 0x16, 0x4c, 0x69, + 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3d, 0x0a, 0x17, 0x4c, 0x69, + 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x41, 0x70, 0x70, 0x52, 0x04, 0x61, 0x70, 0x70, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x46, 0x69, 0x6e, + 0x64, 0x41, 0x6c, 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x40, 0x0a, 0x1a, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, + 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, + 0x70, 0x70, 0x52, 0x04, 0x61, 0x70, 0x70, 0x73, 0x22, 0x60, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x53, 0x69, 0x67, 0x6e, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, + 0x69, 0x67, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x3c, 0x0a, 0x20, 0x52, 0x65, + 0x73, 0x65, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x53, 0x69, 0x67, + 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x22, 0x61, 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, + 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x53, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x32, 0x8f, 0x05, 0x0a, 0x11, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x4d, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x41, 0x70, 0x70, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3f, 0x0a, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x41, 0x70, 0x70, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x3f, 0x0a, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x41, 0x70, 0x70, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x12, 0x47, 0x0a, 0x0e, 0x66, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x41, 0x70, 0x70, 0x12, 0x19, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x6c, + 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x73, 0x12, 0x1a, + 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, + 0x70, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x62, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x66, 0x69, 0x6e, 0x64, 0x41, + 0x6c, 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x73, 0x12, 0x1d, 0x2e, + 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x41, 0x70, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, + 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x41, 0x70, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x1b, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, + 0x53, 0x69, 0x67, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x26, 0x2e, 0x70, 0x62, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, + 0x70, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x68, 0x0a, 0x19, 0x72, 0x65, 0x73, 0x65, 0x74, 0x48, 0x54, 0x54, 0x50, + 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x12, 0x24, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x41, 0x70, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x73, 0x65, + 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x41, 0x70, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x53, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x06, 0x5a, + 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_service_httpdns_app_proto_rawDescOnce sync.Once + file_service_httpdns_app_proto_rawDescData = file_service_httpdns_app_proto_rawDesc +) + +func file_service_httpdns_app_proto_rawDescGZIP() []byte { + file_service_httpdns_app_proto_rawDescOnce.Do(func() { + file_service_httpdns_app_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_httpdns_app_proto_rawDescData) + }) + return file_service_httpdns_app_proto_rawDescData +} + +var file_service_httpdns_app_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_service_httpdns_app_proto_goTypes = []any{ + (*CreateHTTPDNSAppRequest)(nil), // 0: pb.CreateHTTPDNSAppRequest + (*CreateHTTPDNSAppResponse)(nil), // 1: pb.CreateHTTPDNSAppResponse + (*UpdateHTTPDNSAppRequest)(nil), // 2: pb.UpdateHTTPDNSAppRequest + (*DeleteHTTPDNSAppRequest)(nil), // 3: pb.DeleteHTTPDNSAppRequest + (*FindHTTPDNSAppRequest)(nil), // 4: pb.FindHTTPDNSAppRequest + (*FindHTTPDNSAppResponse)(nil), // 5: pb.FindHTTPDNSAppResponse + (*ListHTTPDNSAppsRequest)(nil), // 6: pb.ListHTTPDNSAppsRequest + (*ListHTTPDNSAppsResponse)(nil), // 7: pb.ListHTTPDNSAppsResponse + (*FindAllHTTPDNSAppsRequest)(nil), // 8: pb.FindAllHTTPDNSAppsRequest + (*FindAllHTTPDNSAppsResponse)(nil), // 9: pb.FindAllHTTPDNSAppsResponse + (*UpdateHTTPDNSAppSignEnabledRequest)(nil), // 10: pb.UpdateHTTPDNSAppSignEnabledRequest + (*ResetHTTPDNSAppSignSecretRequest)(nil), // 11: pb.ResetHTTPDNSAppSignSecretRequest + (*ResetHTTPDNSAppSignSecretResponse)(nil), // 12: pb.ResetHTTPDNSAppSignSecretResponse + (*HTTPDNSApp)(nil), // 13: pb.HTTPDNSApp + (*RPCSuccess)(nil), // 14: pb.RPCSuccess +} +var file_service_httpdns_app_proto_depIdxs = []int32{ + 13, // 0: pb.FindHTTPDNSAppResponse.app:type_name -> pb.HTTPDNSApp + 13, // 1: pb.ListHTTPDNSAppsResponse.apps:type_name -> pb.HTTPDNSApp + 13, // 2: pb.FindAllHTTPDNSAppsResponse.apps:type_name -> pb.HTTPDNSApp + 0, // 3: pb.HTTPDNSAppService.createHTTPDNSApp:input_type -> pb.CreateHTTPDNSAppRequest + 2, // 4: pb.HTTPDNSAppService.updateHTTPDNSApp:input_type -> pb.UpdateHTTPDNSAppRequest + 3, // 5: pb.HTTPDNSAppService.deleteHTTPDNSApp:input_type -> pb.DeleteHTTPDNSAppRequest + 4, // 6: pb.HTTPDNSAppService.findHTTPDNSApp:input_type -> pb.FindHTTPDNSAppRequest + 6, // 7: pb.HTTPDNSAppService.listHTTPDNSApps:input_type -> pb.ListHTTPDNSAppsRequest + 8, // 8: pb.HTTPDNSAppService.findAllHTTPDNSApps:input_type -> pb.FindAllHTTPDNSAppsRequest + 10, // 9: pb.HTTPDNSAppService.updateHTTPDNSAppSignEnabled:input_type -> pb.UpdateHTTPDNSAppSignEnabledRequest + 11, // 10: pb.HTTPDNSAppService.resetHTTPDNSAppSignSecret:input_type -> pb.ResetHTTPDNSAppSignSecretRequest + 1, // 11: pb.HTTPDNSAppService.createHTTPDNSApp:output_type -> pb.CreateHTTPDNSAppResponse + 14, // 12: pb.HTTPDNSAppService.updateHTTPDNSApp:output_type -> pb.RPCSuccess + 14, // 13: pb.HTTPDNSAppService.deleteHTTPDNSApp:output_type -> pb.RPCSuccess + 5, // 14: pb.HTTPDNSAppService.findHTTPDNSApp:output_type -> pb.FindHTTPDNSAppResponse + 7, // 15: pb.HTTPDNSAppService.listHTTPDNSApps:output_type -> pb.ListHTTPDNSAppsResponse + 9, // 16: pb.HTTPDNSAppService.findAllHTTPDNSApps:output_type -> pb.FindAllHTTPDNSAppsResponse + 14, // 17: pb.HTTPDNSAppService.updateHTTPDNSAppSignEnabled:output_type -> pb.RPCSuccess + 12, // 18: pb.HTTPDNSAppService.resetHTTPDNSAppSignSecret:output_type -> pb.ResetHTTPDNSAppSignSecretResponse + 11, // [11:19] is the sub-list for method output_type + 3, // [3:11] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_service_httpdns_app_proto_init() } +func file_service_httpdns_app_proto_init() { + if File_service_httpdns_app_proto != nil { + return + } + file_models_model_httpdns_app_proto_init() + file_models_rpc_messages_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_service_httpdns_app_proto_rawDesc, + NumEnums: 0, + NumMessages: 13, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_service_httpdns_app_proto_goTypes, + DependencyIndexes: file_service_httpdns_app_proto_depIdxs, + MessageInfos: file_service_httpdns_app_proto_msgTypes, + }.Build() + File_service_httpdns_app_proto = out.File + file_service_httpdns_app_proto_rawDesc = nil + file_service_httpdns_app_proto_goTypes = nil + file_service_httpdns_app_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_app_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_app_grpc.pb.go new file mode 100644 index 0000000..b01b80e --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_app_grpc.pb.go @@ -0,0 +1,385 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: service_httpdns_app.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 ( + HTTPDNSAppService_CreateHTTPDNSApp_FullMethodName = "/pb.HTTPDNSAppService/createHTTPDNSApp" + HTTPDNSAppService_UpdateHTTPDNSApp_FullMethodName = "/pb.HTTPDNSAppService/updateHTTPDNSApp" + HTTPDNSAppService_DeleteHTTPDNSApp_FullMethodName = "/pb.HTTPDNSAppService/deleteHTTPDNSApp" + HTTPDNSAppService_FindHTTPDNSApp_FullMethodName = "/pb.HTTPDNSAppService/findHTTPDNSApp" + HTTPDNSAppService_ListHTTPDNSApps_FullMethodName = "/pb.HTTPDNSAppService/listHTTPDNSApps" + HTTPDNSAppService_FindAllHTTPDNSApps_FullMethodName = "/pb.HTTPDNSAppService/findAllHTTPDNSApps" + HTTPDNSAppService_UpdateHTTPDNSAppSignEnabled_FullMethodName = "/pb.HTTPDNSAppService/updateHTTPDNSAppSignEnabled" + HTTPDNSAppService_ResetHTTPDNSAppSignSecret_FullMethodName = "/pb.HTTPDNSAppService/resetHTTPDNSAppSignSecret" +) + +// HTTPDNSAppServiceClient is the client API for HTTPDNSAppService 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. +type HTTPDNSAppServiceClient interface { + CreateHTTPDNSApp(ctx context.Context, in *CreateHTTPDNSAppRequest, opts ...grpc.CallOption) (*CreateHTTPDNSAppResponse, error) + UpdateHTTPDNSApp(ctx context.Context, in *UpdateHTTPDNSAppRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + DeleteHTTPDNSApp(ctx context.Context, in *DeleteHTTPDNSAppRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + FindHTTPDNSApp(ctx context.Context, in *FindHTTPDNSAppRequest, opts ...grpc.CallOption) (*FindHTTPDNSAppResponse, error) + ListHTTPDNSApps(ctx context.Context, in *ListHTTPDNSAppsRequest, opts ...grpc.CallOption) (*ListHTTPDNSAppsResponse, error) + FindAllHTTPDNSApps(ctx context.Context, in *FindAllHTTPDNSAppsRequest, opts ...grpc.CallOption) (*FindAllHTTPDNSAppsResponse, error) + UpdateHTTPDNSAppSignEnabled(ctx context.Context, in *UpdateHTTPDNSAppSignEnabledRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + ResetHTTPDNSAppSignSecret(ctx context.Context, in *ResetHTTPDNSAppSignSecretRequest, opts ...grpc.CallOption) (*ResetHTTPDNSAppSignSecretResponse, error) +} + +type hTTPDNSAppServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHTTPDNSAppServiceClient(cc grpc.ClientConnInterface) HTTPDNSAppServiceClient { + return &hTTPDNSAppServiceClient{cc} +} + +func (c *hTTPDNSAppServiceClient) CreateHTTPDNSApp(ctx context.Context, in *CreateHTTPDNSAppRequest, opts ...grpc.CallOption) (*CreateHTTPDNSAppResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateHTTPDNSAppResponse) + err := c.cc.Invoke(ctx, HTTPDNSAppService_CreateHTTPDNSApp_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSAppServiceClient) UpdateHTTPDNSApp(ctx context.Context, in *UpdateHTTPDNSAppRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSAppService_UpdateHTTPDNSApp_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSAppServiceClient) DeleteHTTPDNSApp(ctx context.Context, in *DeleteHTTPDNSAppRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSAppService_DeleteHTTPDNSApp_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSAppServiceClient) FindHTTPDNSApp(ctx context.Context, in *FindHTTPDNSAppRequest, opts ...grpc.CallOption) (*FindHTTPDNSAppResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(FindHTTPDNSAppResponse) + err := c.cc.Invoke(ctx, HTTPDNSAppService_FindHTTPDNSApp_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSAppServiceClient) ListHTTPDNSApps(ctx context.Context, in *ListHTTPDNSAppsRequest, opts ...grpc.CallOption) (*ListHTTPDNSAppsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListHTTPDNSAppsResponse) + err := c.cc.Invoke(ctx, HTTPDNSAppService_ListHTTPDNSApps_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSAppServiceClient) FindAllHTTPDNSApps(ctx context.Context, in *FindAllHTTPDNSAppsRequest, opts ...grpc.CallOption) (*FindAllHTTPDNSAppsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(FindAllHTTPDNSAppsResponse) + err := c.cc.Invoke(ctx, HTTPDNSAppService_FindAllHTTPDNSApps_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSAppServiceClient) UpdateHTTPDNSAppSignEnabled(ctx context.Context, in *UpdateHTTPDNSAppSignEnabledRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSAppService_UpdateHTTPDNSAppSignEnabled_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSAppServiceClient) ResetHTTPDNSAppSignSecret(ctx context.Context, in *ResetHTTPDNSAppSignSecretRequest, opts ...grpc.CallOption) (*ResetHTTPDNSAppSignSecretResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResetHTTPDNSAppSignSecretResponse) + err := c.cc.Invoke(ctx, HTTPDNSAppService_ResetHTTPDNSAppSignSecret_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HTTPDNSAppServiceServer is the server API for HTTPDNSAppService service. +// All implementations should embed UnimplementedHTTPDNSAppServiceServer +// for forward compatibility. +type HTTPDNSAppServiceServer interface { + CreateHTTPDNSApp(context.Context, *CreateHTTPDNSAppRequest) (*CreateHTTPDNSAppResponse, error) + UpdateHTTPDNSApp(context.Context, *UpdateHTTPDNSAppRequest) (*RPCSuccess, error) + DeleteHTTPDNSApp(context.Context, *DeleteHTTPDNSAppRequest) (*RPCSuccess, error) + FindHTTPDNSApp(context.Context, *FindHTTPDNSAppRequest) (*FindHTTPDNSAppResponse, error) + ListHTTPDNSApps(context.Context, *ListHTTPDNSAppsRequest) (*ListHTTPDNSAppsResponse, error) + FindAllHTTPDNSApps(context.Context, *FindAllHTTPDNSAppsRequest) (*FindAllHTTPDNSAppsResponse, error) + UpdateHTTPDNSAppSignEnabled(context.Context, *UpdateHTTPDNSAppSignEnabledRequest) (*RPCSuccess, error) + ResetHTTPDNSAppSignSecret(context.Context, *ResetHTTPDNSAppSignSecretRequest) (*ResetHTTPDNSAppSignSecretResponse, error) +} + +// UnimplementedHTTPDNSAppServiceServer 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 UnimplementedHTTPDNSAppServiceServer struct{} + +func (UnimplementedHTTPDNSAppServiceServer) CreateHTTPDNSApp(context.Context, *CreateHTTPDNSAppRequest) (*CreateHTTPDNSAppResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHTTPDNSApp not implemented") +} +func (UnimplementedHTTPDNSAppServiceServer) UpdateHTTPDNSApp(context.Context, *UpdateHTTPDNSAppRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSApp not implemented") +} +func (UnimplementedHTTPDNSAppServiceServer) DeleteHTTPDNSApp(context.Context, *DeleteHTTPDNSAppRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteHTTPDNSApp not implemented") +} +func (UnimplementedHTTPDNSAppServiceServer) FindHTTPDNSApp(context.Context, *FindHTTPDNSAppRequest) (*FindHTTPDNSAppResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindHTTPDNSApp not implemented") +} +func (UnimplementedHTTPDNSAppServiceServer) ListHTTPDNSApps(context.Context, *ListHTTPDNSAppsRequest) (*ListHTTPDNSAppsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListHTTPDNSApps not implemented") +} +func (UnimplementedHTTPDNSAppServiceServer) FindAllHTTPDNSApps(context.Context, *FindAllHTTPDNSAppsRequest) (*FindAllHTTPDNSAppsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindAllHTTPDNSApps not implemented") +} +func (UnimplementedHTTPDNSAppServiceServer) UpdateHTTPDNSAppSignEnabled(context.Context, *UpdateHTTPDNSAppSignEnabledRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSAppSignEnabled not implemented") +} +func (UnimplementedHTTPDNSAppServiceServer) ResetHTTPDNSAppSignSecret(context.Context, *ResetHTTPDNSAppSignSecretRequest) (*ResetHTTPDNSAppSignSecretResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResetHTTPDNSAppSignSecret not implemented") +} +func (UnimplementedHTTPDNSAppServiceServer) testEmbeddedByValue() {} + +// UnsafeHTTPDNSAppServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HTTPDNSAppServiceServer will +// result in compilation errors. +type UnsafeHTTPDNSAppServiceServer interface { + mustEmbedUnimplementedHTTPDNSAppServiceServer() +} + +func RegisterHTTPDNSAppServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSAppServiceServer) { + // If the following call pancis, it indicates UnimplementedHTTPDNSAppServiceServer 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(&HTTPDNSAppService_ServiceDesc, srv) +} + +func _HTTPDNSAppService_CreateHTTPDNSApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateHTTPDNSAppRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAppServiceServer).CreateHTTPDNSApp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAppService_CreateHTTPDNSApp_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAppServiceServer).CreateHTTPDNSApp(ctx, req.(*CreateHTTPDNSAppRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSAppService_UpdateHTTPDNSApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSAppRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAppServiceServer).UpdateHTTPDNSApp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAppService_UpdateHTTPDNSApp_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAppServiceServer).UpdateHTTPDNSApp(ctx, req.(*UpdateHTTPDNSAppRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSAppService_DeleteHTTPDNSApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteHTTPDNSAppRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAppServiceServer).DeleteHTTPDNSApp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAppService_DeleteHTTPDNSApp_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAppServiceServer).DeleteHTTPDNSApp(ctx, req.(*DeleteHTTPDNSAppRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSAppService_FindHTTPDNSApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindHTTPDNSAppRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAppServiceServer).FindHTTPDNSApp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAppService_FindHTTPDNSApp_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAppServiceServer).FindHTTPDNSApp(ctx, req.(*FindHTTPDNSAppRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSAppService_ListHTTPDNSApps_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListHTTPDNSAppsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAppServiceServer).ListHTTPDNSApps(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAppService_ListHTTPDNSApps_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAppServiceServer).ListHTTPDNSApps(ctx, req.(*ListHTTPDNSAppsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSAppService_FindAllHTTPDNSApps_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindAllHTTPDNSAppsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAppServiceServer).FindAllHTTPDNSApps(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAppService_FindAllHTTPDNSApps_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAppServiceServer).FindAllHTTPDNSApps(ctx, req.(*FindAllHTTPDNSAppsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSAppService_UpdateHTTPDNSAppSignEnabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSAppSignEnabledRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAppServiceServer).UpdateHTTPDNSAppSignEnabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAppService_UpdateHTTPDNSAppSignEnabled_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAppServiceServer).UpdateHTTPDNSAppSignEnabled(ctx, req.(*UpdateHTTPDNSAppSignEnabledRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSAppService_ResetHTTPDNSAppSignSecret_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResetHTTPDNSAppSignSecretRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSAppServiceServer).ResetHTTPDNSAppSignSecret(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSAppService_ResetHTTPDNSAppSignSecret_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSAppServiceServer).ResetHTTPDNSAppSignSecret(ctx, req.(*ResetHTTPDNSAppSignSecretRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HTTPDNSAppService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSAppService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HTTPDNSAppService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.HTTPDNSAppService", + HandlerType: (*HTTPDNSAppServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "createHTTPDNSApp", + Handler: _HTTPDNSAppService_CreateHTTPDNSApp_Handler, + }, + { + MethodName: "updateHTTPDNSApp", + Handler: _HTTPDNSAppService_UpdateHTTPDNSApp_Handler, + }, + { + MethodName: "deleteHTTPDNSApp", + Handler: _HTTPDNSAppService_DeleteHTTPDNSApp_Handler, + }, + { + MethodName: "findHTTPDNSApp", + Handler: _HTTPDNSAppService_FindHTTPDNSApp_Handler, + }, + { + MethodName: "listHTTPDNSApps", + Handler: _HTTPDNSAppService_ListHTTPDNSApps_Handler, + }, + { + MethodName: "findAllHTTPDNSApps", + Handler: _HTTPDNSAppService_FindAllHTTPDNSApps_Handler, + }, + { + MethodName: "updateHTTPDNSAppSignEnabled", + Handler: _HTTPDNSAppService_UpdateHTTPDNSAppSignEnabled_Handler, + }, + { + MethodName: "resetHTTPDNSAppSignSecret", + Handler: _HTTPDNSAppService_ResetHTTPDNSAppSignSecret_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service_httpdns_app.proto", +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_cluster.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_cluster.pb.go new file mode 100644 index 0000000..885607e --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_cluster.pb.go @@ -0,0 +1,967 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: service_httpdns_cluster.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 CreateHTTPDNSClusterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + ServiceDomain string `protobuf:"bytes,2,opt,name=serviceDomain,proto3" json:"serviceDomain,omitempty"` + DefaultTTL int32 `protobuf:"varint,3,opt,name=defaultTTL,proto3" json:"defaultTTL,omitempty"` + FallbackTimeoutMs int32 `protobuf:"varint,4,opt,name=fallbackTimeoutMs,proto3" json:"fallbackTimeoutMs,omitempty"` + InstallDir string `protobuf:"bytes,5,opt,name=installDir,proto3" json:"installDir,omitempty"` + TlsPolicyJSON []byte `protobuf:"bytes,6,opt,name=tlsPolicyJSON,proto3" json:"tlsPolicyJSON,omitempty"` + IsOn bool `protobuf:"varint,7,opt,name=isOn,proto3" json:"isOn,omitempty"` + IsDefault bool `protobuf:"varint,8,opt,name=isDefault,proto3" json:"isDefault,omitempty"` +} + +func (x *CreateHTTPDNSClusterRequest) Reset() { + *x = CreateHTTPDNSClusterRequest{} + mi := &file_service_httpdns_cluster_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSClusterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSClusterRequest) ProtoMessage() {} + +func (x *CreateHTTPDNSClusterRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_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 CreateHTTPDNSClusterRequest.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSClusterRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateHTTPDNSClusterRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateHTTPDNSClusterRequest) GetServiceDomain() string { + if x != nil { + return x.ServiceDomain + } + return "" +} + +func (x *CreateHTTPDNSClusterRequest) GetDefaultTTL() int32 { + if x != nil { + return x.DefaultTTL + } + return 0 +} + +func (x *CreateHTTPDNSClusterRequest) GetFallbackTimeoutMs() int32 { + if x != nil { + return x.FallbackTimeoutMs + } + return 0 +} + +func (x *CreateHTTPDNSClusterRequest) GetInstallDir() string { + if x != nil { + return x.InstallDir + } + return "" +} + +func (x *CreateHTTPDNSClusterRequest) GetTlsPolicyJSON() []byte { + if x != nil { + return x.TlsPolicyJSON + } + return nil +} + +func (x *CreateHTTPDNSClusterRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *CreateHTTPDNSClusterRequest) GetIsDefault() bool { + if x != nil { + return x.IsDefault + } + return false +} + +type CreateHTTPDNSClusterResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` +} + +func (x *CreateHTTPDNSClusterResponse) Reset() { + *x = CreateHTTPDNSClusterResponse{} + mi := &file_service_httpdns_cluster_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSClusterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSClusterResponse) ProtoMessage() {} + +func (x *CreateHTTPDNSClusterResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_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 CreateHTTPDNSClusterResponse.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSClusterResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateHTTPDNSClusterResponse) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +type UpdateHTTPDNSClusterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + ServiceDomain string `protobuf:"bytes,3,opt,name=serviceDomain,proto3" json:"serviceDomain,omitempty"` + DefaultTTL int32 `protobuf:"varint,4,opt,name=defaultTTL,proto3" json:"defaultTTL,omitempty"` + FallbackTimeoutMs int32 `protobuf:"varint,5,opt,name=fallbackTimeoutMs,proto3" json:"fallbackTimeoutMs,omitempty"` + InstallDir string `protobuf:"bytes,6,opt,name=installDir,proto3" json:"installDir,omitempty"` + TlsPolicyJSON []byte `protobuf:"bytes,7,opt,name=tlsPolicyJSON,proto3" json:"tlsPolicyJSON,omitempty"` + IsOn bool `protobuf:"varint,8,opt,name=isOn,proto3" json:"isOn,omitempty"` + IsDefault bool `protobuf:"varint,9,opt,name=isDefault,proto3" json:"isDefault,omitempty"` +} + +func (x *UpdateHTTPDNSClusterRequest) Reset() { + *x = UpdateHTTPDNSClusterRequest{} + mi := &file_service_httpdns_cluster_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSClusterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSClusterRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSClusterRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_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 UpdateHTTPDNSClusterRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSClusterRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateHTTPDNSClusterRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +func (x *UpdateHTTPDNSClusterRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateHTTPDNSClusterRequest) GetServiceDomain() string { + if x != nil { + return x.ServiceDomain + } + return "" +} + +func (x *UpdateHTTPDNSClusterRequest) GetDefaultTTL() int32 { + if x != nil { + return x.DefaultTTL + } + return 0 +} + +func (x *UpdateHTTPDNSClusterRequest) GetFallbackTimeoutMs() int32 { + if x != nil { + return x.FallbackTimeoutMs + } + return 0 +} + +func (x *UpdateHTTPDNSClusterRequest) GetInstallDir() string { + if x != nil { + return x.InstallDir + } + return "" +} + +func (x *UpdateHTTPDNSClusterRequest) GetTlsPolicyJSON() []byte { + if x != nil { + return x.TlsPolicyJSON + } + return nil +} + +func (x *UpdateHTTPDNSClusterRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +func (x *UpdateHTTPDNSClusterRequest) GetIsDefault() bool { + if x != nil { + return x.IsDefault + } + return false +} + +type DeleteHTTPDNSClusterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` +} + +func (x *DeleteHTTPDNSClusterRequest) Reset() { + *x = DeleteHTTPDNSClusterRequest{} + mi := &file_service_httpdns_cluster_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteHTTPDNSClusterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteHTTPDNSClusterRequest) ProtoMessage() {} + +func (x *DeleteHTTPDNSClusterRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_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 DeleteHTTPDNSClusterRequest.ProtoReflect.Descriptor instead. +func (*DeleteHTTPDNSClusterRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{3} +} + +func (x *DeleteHTTPDNSClusterRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +type FindHTTPDNSClusterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` +} + +func (x *FindHTTPDNSClusterRequest) Reset() { + *x = FindHTTPDNSClusterRequest{} + mi := &file_service_httpdns_cluster_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindHTTPDNSClusterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindHTTPDNSClusterRequest) ProtoMessage() {} + +func (x *FindHTTPDNSClusterRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_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 FindHTTPDNSClusterRequest.ProtoReflect.Descriptor instead. +func (*FindHTTPDNSClusterRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{4} +} + +func (x *FindHTTPDNSClusterRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +type FindHTTPDNSClusterResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cluster *HTTPDNSCluster `protobuf:"bytes,1,opt,name=cluster,proto3" json:"cluster,omitempty"` +} + +func (x *FindHTTPDNSClusterResponse) Reset() { + *x = FindHTTPDNSClusterResponse{} + mi := &file_service_httpdns_cluster_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindHTTPDNSClusterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindHTTPDNSClusterResponse) ProtoMessage() {} + +func (x *FindHTTPDNSClusterResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_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 FindHTTPDNSClusterResponse.ProtoReflect.Descriptor instead. +func (*FindHTTPDNSClusterResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{5} +} + +func (x *FindHTTPDNSClusterResponse) GetCluster() *HTTPDNSCluster { + if x != nil { + return x.Cluster + } + return nil +} + +type ListHTTPDNSClustersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Offset int64 `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"` + Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + Keyword string `protobuf:"bytes,3,opt,name=keyword,proto3" json:"keyword,omitempty"` +} + +func (x *ListHTTPDNSClustersRequest) Reset() { + *x = ListHTTPDNSClustersRequest{} + mi := &file_service_httpdns_cluster_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSClustersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSClustersRequest) ProtoMessage() {} + +func (x *ListHTTPDNSClustersRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_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 ListHTTPDNSClustersRequest.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSClustersRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{6} +} + +func (x *ListHTTPDNSClustersRequest) GetOffset() int64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListHTTPDNSClustersRequest) GetSize() int64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ListHTTPDNSClustersRequest) GetKeyword() string { + if x != nil { + return x.Keyword + } + return "" +} + +type ListHTTPDNSClustersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clusters []*HTTPDNSCluster `protobuf:"bytes,1,rep,name=clusters,proto3" json:"clusters,omitempty"` +} + +func (x *ListHTTPDNSClustersResponse) Reset() { + *x = ListHTTPDNSClustersResponse{} + mi := &file_service_httpdns_cluster_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSClustersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSClustersResponse) ProtoMessage() {} + +func (x *ListHTTPDNSClustersResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_proto_msgTypes[7] + 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 ListHTTPDNSClustersResponse.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSClustersResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{7} +} + +func (x *ListHTTPDNSClustersResponse) GetClusters() []*HTTPDNSCluster { + if x != nil { + return x.Clusters + } + return nil +} + +type FindAllHTTPDNSClustersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FindAllHTTPDNSClustersRequest) Reset() { + *x = FindAllHTTPDNSClustersRequest{} + mi := &file_service_httpdns_cluster_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindAllHTTPDNSClustersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindAllHTTPDNSClustersRequest) ProtoMessage() {} + +func (x *FindAllHTTPDNSClustersRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_proto_msgTypes[8] + 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 FindAllHTTPDNSClustersRequest.ProtoReflect.Descriptor instead. +func (*FindAllHTTPDNSClustersRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{8} +} + +type FindAllHTTPDNSClustersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clusters []*HTTPDNSCluster `protobuf:"bytes,1,rep,name=clusters,proto3" json:"clusters,omitempty"` +} + +func (x *FindAllHTTPDNSClustersResponse) Reset() { + *x = FindAllHTTPDNSClustersResponse{} + mi := &file_service_httpdns_cluster_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindAllHTTPDNSClustersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindAllHTTPDNSClustersResponse) ProtoMessage() {} + +func (x *FindAllHTTPDNSClustersResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_proto_msgTypes[9] + 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 FindAllHTTPDNSClustersResponse.ProtoReflect.Descriptor instead. +func (*FindAllHTTPDNSClustersResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{9} +} + +func (x *FindAllHTTPDNSClustersResponse) GetClusters() []*HTTPDNSCluster { + if x != nil { + return x.Clusters + } + return nil +} + +type UpdateHTTPDNSClusterDefaultRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` +} + +func (x *UpdateHTTPDNSClusterDefaultRequest) Reset() { + *x = UpdateHTTPDNSClusterDefaultRequest{} + mi := &file_service_httpdns_cluster_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSClusterDefaultRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSClusterDefaultRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSClusterDefaultRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_proto_msgTypes[10] + 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 UpdateHTTPDNSClusterDefaultRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSClusterDefaultRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{10} +} + +func (x *UpdateHTTPDNSClusterDefaultRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +type ListHTTPDNSNodesWithClusterIdRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` +} + +func (x *ListHTTPDNSNodesWithClusterIdRequest) Reset() { + *x = ListHTTPDNSNodesWithClusterIdRequest{} + mi := &file_service_httpdns_cluster_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSNodesWithClusterIdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSNodesWithClusterIdRequest) ProtoMessage() {} + +func (x *ListHTTPDNSNodesWithClusterIdRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_proto_msgTypes[11] + 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 ListHTTPDNSNodesWithClusterIdRequest.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSNodesWithClusterIdRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{11} +} + +func (x *ListHTTPDNSNodesWithClusterIdRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +type ListHTTPDNSNodesWithClusterIdResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*HTTPDNSNode `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` +} + +func (x *ListHTTPDNSNodesWithClusterIdResponse) Reset() { + *x = ListHTTPDNSNodesWithClusterIdResponse{} + mi := &file_service_httpdns_cluster_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSNodesWithClusterIdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSNodesWithClusterIdResponse) ProtoMessage() {} + +func (x *ListHTTPDNSNodesWithClusterIdResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_cluster_proto_msgTypes[12] + 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 ListHTTPDNSNodesWithClusterIdResponse.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSNodesWithClusterIdResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_cluster_proto_rawDescGZIP(), []int{12} +} + +func (x *ListHTTPDNSNodesWithClusterIdResponse) GetNodes() []*HTTPDNSNode { + if x != nil { + return x.Nodes + } + return nil +} + +var File_service_httpdns_cluster_proto protoreflect.FileDescriptor + +var file_service_httpdns_cluster_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, + 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x02, 0x70, 0x62, 0x1a, 0x22, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x6f, + 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, + 0x2f, 0x72, 0x70, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x02, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x0a, + 0x0a, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x54, 0x4c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0a, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x54, 0x4c, 0x12, 0x2c, 0x0a, + 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x4d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x74, + 0x6c, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0d, 0x74, 0x6c, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4a, 0x53, 0x4f, + 0x4e, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x22, 0x3c, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, + 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, + 0x64, 0x22, 0xbb, 0x02, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, + 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x54, 0x54, 0x4c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x54, 0x4c, 0x12, 0x2c, 0x0a, 0x11, 0x66, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6c, 0x73, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, + 0x74, 0x6c, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4a, 0x53, 0x4f, 0x4e, 0x12, 0x12, 0x0a, + 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, + 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, + 0x3b, 0x0a, 0x1b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, + 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x39, 0x0a, 0x19, + 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4a, 0x0a, 0x1a, 0x46, 0x69, 0x6e, 0x64, 0x48, + 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, + 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x22, 0x62, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x4d, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x48, + 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x22, 0x1f, 0x0a, 0x1d, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, + 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x50, 0x0a, 0x1e, 0x46, 0x69, 0x6e, 0x64, 0x41, + 0x6c, 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x62, + 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x22, 0x42, 0x0a, 0x22, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x44, 0x0a, + 0x24, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, + 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x49, 0x64, 0x22, 0x4e, 0x0a, 0x25, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, + 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, + 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, + 0x64, 0x65, 0x73, 0x32, 0xdf, 0x05, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x59, 0x0a, + 0x14, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x14, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x12, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, + 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x47, 0x0a, 0x14, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, + 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x53, 0x0a, 0x12, 0x66, 0x69, + 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x12, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x56, 0x0a, 0x13, 0x6c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x16, 0x66, 0x69, 0x6e, 0x64, 0x41, + 0x6c, 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x21, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, + 0x6c, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x1b, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x26, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, + 0x74, 0x0a, 0x1d, 0x6c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, + 0x64, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x28, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x62, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x73, + 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_service_httpdns_cluster_proto_rawDescOnce sync.Once + file_service_httpdns_cluster_proto_rawDescData = file_service_httpdns_cluster_proto_rawDesc +) + +func file_service_httpdns_cluster_proto_rawDescGZIP() []byte { + file_service_httpdns_cluster_proto_rawDescOnce.Do(func() { + file_service_httpdns_cluster_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_httpdns_cluster_proto_rawDescData) + }) + return file_service_httpdns_cluster_proto_rawDescData +} + +var file_service_httpdns_cluster_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_service_httpdns_cluster_proto_goTypes = []any{ + (*CreateHTTPDNSClusterRequest)(nil), // 0: pb.CreateHTTPDNSClusterRequest + (*CreateHTTPDNSClusterResponse)(nil), // 1: pb.CreateHTTPDNSClusterResponse + (*UpdateHTTPDNSClusterRequest)(nil), // 2: pb.UpdateHTTPDNSClusterRequest + (*DeleteHTTPDNSClusterRequest)(nil), // 3: pb.DeleteHTTPDNSClusterRequest + (*FindHTTPDNSClusterRequest)(nil), // 4: pb.FindHTTPDNSClusterRequest + (*FindHTTPDNSClusterResponse)(nil), // 5: pb.FindHTTPDNSClusterResponse + (*ListHTTPDNSClustersRequest)(nil), // 6: pb.ListHTTPDNSClustersRequest + (*ListHTTPDNSClustersResponse)(nil), // 7: pb.ListHTTPDNSClustersResponse + (*FindAllHTTPDNSClustersRequest)(nil), // 8: pb.FindAllHTTPDNSClustersRequest + (*FindAllHTTPDNSClustersResponse)(nil), // 9: pb.FindAllHTTPDNSClustersResponse + (*UpdateHTTPDNSClusterDefaultRequest)(nil), // 10: pb.UpdateHTTPDNSClusterDefaultRequest + (*ListHTTPDNSNodesWithClusterIdRequest)(nil), // 11: pb.ListHTTPDNSNodesWithClusterIdRequest + (*ListHTTPDNSNodesWithClusterIdResponse)(nil), // 12: pb.ListHTTPDNSNodesWithClusterIdResponse + (*HTTPDNSCluster)(nil), // 13: pb.HTTPDNSCluster + (*HTTPDNSNode)(nil), // 14: pb.HTTPDNSNode + (*RPCSuccess)(nil), // 15: pb.RPCSuccess +} +var file_service_httpdns_cluster_proto_depIdxs = []int32{ + 13, // 0: pb.FindHTTPDNSClusterResponse.cluster:type_name -> pb.HTTPDNSCluster + 13, // 1: pb.ListHTTPDNSClustersResponse.clusters:type_name -> pb.HTTPDNSCluster + 13, // 2: pb.FindAllHTTPDNSClustersResponse.clusters:type_name -> pb.HTTPDNSCluster + 14, // 3: pb.ListHTTPDNSNodesWithClusterIdResponse.nodes:type_name -> pb.HTTPDNSNode + 0, // 4: pb.HTTPDNSClusterService.createHTTPDNSCluster:input_type -> pb.CreateHTTPDNSClusterRequest + 2, // 5: pb.HTTPDNSClusterService.updateHTTPDNSCluster:input_type -> pb.UpdateHTTPDNSClusterRequest + 3, // 6: pb.HTTPDNSClusterService.deleteHTTPDNSCluster:input_type -> pb.DeleteHTTPDNSClusterRequest + 4, // 7: pb.HTTPDNSClusterService.findHTTPDNSCluster:input_type -> pb.FindHTTPDNSClusterRequest + 6, // 8: pb.HTTPDNSClusterService.listHTTPDNSClusters:input_type -> pb.ListHTTPDNSClustersRequest + 8, // 9: pb.HTTPDNSClusterService.findAllHTTPDNSClusters:input_type -> pb.FindAllHTTPDNSClustersRequest + 10, // 10: pb.HTTPDNSClusterService.updateHTTPDNSClusterDefault:input_type -> pb.UpdateHTTPDNSClusterDefaultRequest + 11, // 11: pb.HTTPDNSClusterService.listHTTPDNSNodesWithClusterId:input_type -> pb.ListHTTPDNSNodesWithClusterIdRequest + 1, // 12: pb.HTTPDNSClusterService.createHTTPDNSCluster:output_type -> pb.CreateHTTPDNSClusterResponse + 15, // 13: pb.HTTPDNSClusterService.updateHTTPDNSCluster:output_type -> pb.RPCSuccess + 15, // 14: pb.HTTPDNSClusterService.deleteHTTPDNSCluster:output_type -> pb.RPCSuccess + 5, // 15: pb.HTTPDNSClusterService.findHTTPDNSCluster:output_type -> pb.FindHTTPDNSClusterResponse + 7, // 16: pb.HTTPDNSClusterService.listHTTPDNSClusters:output_type -> pb.ListHTTPDNSClustersResponse + 9, // 17: pb.HTTPDNSClusterService.findAllHTTPDNSClusters:output_type -> pb.FindAllHTTPDNSClustersResponse + 15, // 18: pb.HTTPDNSClusterService.updateHTTPDNSClusterDefault:output_type -> pb.RPCSuccess + 12, // 19: pb.HTTPDNSClusterService.listHTTPDNSNodesWithClusterId:output_type -> pb.ListHTTPDNSNodesWithClusterIdResponse + 12, // [12:20] is the sub-list for method output_type + 4, // [4:12] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_service_httpdns_cluster_proto_init() } +func file_service_httpdns_cluster_proto_init() { + if File_service_httpdns_cluster_proto != nil { + return + } + file_models_model_httpdns_cluster_proto_init() + file_models_model_httpdns_node_proto_init() + file_models_rpc_messages_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_service_httpdns_cluster_proto_rawDesc, + NumEnums: 0, + NumMessages: 13, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_service_httpdns_cluster_proto_goTypes, + DependencyIndexes: file_service_httpdns_cluster_proto_depIdxs, + MessageInfos: file_service_httpdns_cluster_proto_msgTypes, + }.Build() + File_service_httpdns_cluster_proto = out.File + file_service_httpdns_cluster_proto_rawDesc = nil + file_service_httpdns_cluster_proto_goTypes = nil + file_service_httpdns_cluster_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_cluster_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_cluster_grpc.pb.go new file mode 100644 index 0000000..825f8b6 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_cluster_grpc.pb.go @@ -0,0 +1,385 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: service_httpdns_cluster.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 ( + HTTPDNSClusterService_CreateHTTPDNSCluster_FullMethodName = "/pb.HTTPDNSClusterService/createHTTPDNSCluster" + HTTPDNSClusterService_UpdateHTTPDNSCluster_FullMethodName = "/pb.HTTPDNSClusterService/updateHTTPDNSCluster" + HTTPDNSClusterService_DeleteHTTPDNSCluster_FullMethodName = "/pb.HTTPDNSClusterService/deleteHTTPDNSCluster" + HTTPDNSClusterService_FindHTTPDNSCluster_FullMethodName = "/pb.HTTPDNSClusterService/findHTTPDNSCluster" + HTTPDNSClusterService_ListHTTPDNSClusters_FullMethodName = "/pb.HTTPDNSClusterService/listHTTPDNSClusters" + HTTPDNSClusterService_FindAllHTTPDNSClusters_FullMethodName = "/pb.HTTPDNSClusterService/findAllHTTPDNSClusters" + HTTPDNSClusterService_UpdateHTTPDNSClusterDefault_FullMethodName = "/pb.HTTPDNSClusterService/updateHTTPDNSClusterDefault" + HTTPDNSClusterService_ListHTTPDNSNodesWithClusterId_FullMethodName = "/pb.HTTPDNSClusterService/listHTTPDNSNodesWithClusterId" +) + +// HTTPDNSClusterServiceClient is the client API for HTTPDNSClusterService 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. +type HTTPDNSClusterServiceClient interface { + CreateHTTPDNSCluster(ctx context.Context, in *CreateHTTPDNSClusterRequest, opts ...grpc.CallOption) (*CreateHTTPDNSClusterResponse, error) + UpdateHTTPDNSCluster(ctx context.Context, in *UpdateHTTPDNSClusterRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + DeleteHTTPDNSCluster(ctx context.Context, in *DeleteHTTPDNSClusterRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + FindHTTPDNSCluster(ctx context.Context, in *FindHTTPDNSClusterRequest, opts ...grpc.CallOption) (*FindHTTPDNSClusterResponse, error) + ListHTTPDNSClusters(ctx context.Context, in *ListHTTPDNSClustersRequest, opts ...grpc.CallOption) (*ListHTTPDNSClustersResponse, error) + FindAllHTTPDNSClusters(ctx context.Context, in *FindAllHTTPDNSClustersRequest, opts ...grpc.CallOption) (*FindAllHTTPDNSClustersResponse, error) + UpdateHTTPDNSClusterDefault(ctx context.Context, in *UpdateHTTPDNSClusterDefaultRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + ListHTTPDNSNodesWithClusterId(ctx context.Context, in *ListHTTPDNSNodesWithClusterIdRequest, opts ...grpc.CallOption) (*ListHTTPDNSNodesWithClusterIdResponse, error) +} + +type hTTPDNSClusterServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHTTPDNSClusterServiceClient(cc grpc.ClientConnInterface) HTTPDNSClusterServiceClient { + return &hTTPDNSClusterServiceClient{cc} +} + +func (c *hTTPDNSClusterServiceClient) CreateHTTPDNSCluster(ctx context.Context, in *CreateHTTPDNSClusterRequest, opts ...grpc.CallOption) (*CreateHTTPDNSClusterResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateHTTPDNSClusterResponse) + err := c.cc.Invoke(ctx, HTTPDNSClusterService_CreateHTTPDNSCluster_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSClusterServiceClient) UpdateHTTPDNSCluster(ctx context.Context, in *UpdateHTTPDNSClusterRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSClusterService_UpdateHTTPDNSCluster_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSClusterServiceClient) DeleteHTTPDNSCluster(ctx context.Context, in *DeleteHTTPDNSClusterRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSClusterService_DeleteHTTPDNSCluster_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSClusterServiceClient) FindHTTPDNSCluster(ctx context.Context, in *FindHTTPDNSClusterRequest, opts ...grpc.CallOption) (*FindHTTPDNSClusterResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(FindHTTPDNSClusterResponse) + err := c.cc.Invoke(ctx, HTTPDNSClusterService_FindHTTPDNSCluster_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSClusterServiceClient) ListHTTPDNSClusters(ctx context.Context, in *ListHTTPDNSClustersRequest, opts ...grpc.CallOption) (*ListHTTPDNSClustersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListHTTPDNSClustersResponse) + err := c.cc.Invoke(ctx, HTTPDNSClusterService_ListHTTPDNSClusters_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSClusterServiceClient) FindAllHTTPDNSClusters(ctx context.Context, in *FindAllHTTPDNSClustersRequest, opts ...grpc.CallOption) (*FindAllHTTPDNSClustersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(FindAllHTTPDNSClustersResponse) + err := c.cc.Invoke(ctx, HTTPDNSClusterService_FindAllHTTPDNSClusters_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSClusterServiceClient) UpdateHTTPDNSClusterDefault(ctx context.Context, in *UpdateHTTPDNSClusterDefaultRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSClusterService_UpdateHTTPDNSClusterDefault_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSClusterServiceClient) ListHTTPDNSNodesWithClusterId(ctx context.Context, in *ListHTTPDNSNodesWithClusterIdRequest, opts ...grpc.CallOption) (*ListHTTPDNSNodesWithClusterIdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListHTTPDNSNodesWithClusterIdResponse) + err := c.cc.Invoke(ctx, HTTPDNSClusterService_ListHTTPDNSNodesWithClusterId_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HTTPDNSClusterServiceServer is the server API for HTTPDNSClusterService service. +// All implementations should embed UnimplementedHTTPDNSClusterServiceServer +// for forward compatibility. +type HTTPDNSClusterServiceServer interface { + CreateHTTPDNSCluster(context.Context, *CreateHTTPDNSClusterRequest) (*CreateHTTPDNSClusterResponse, error) + UpdateHTTPDNSCluster(context.Context, *UpdateHTTPDNSClusterRequest) (*RPCSuccess, error) + DeleteHTTPDNSCluster(context.Context, *DeleteHTTPDNSClusterRequest) (*RPCSuccess, error) + FindHTTPDNSCluster(context.Context, *FindHTTPDNSClusterRequest) (*FindHTTPDNSClusterResponse, error) + ListHTTPDNSClusters(context.Context, *ListHTTPDNSClustersRequest) (*ListHTTPDNSClustersResponse, error) + FindAllHTTPDNSClusters(context.Context, *FindAllHTTPDNSClustersRequest) (*FindAllHTTPDNSClustersResponse, error) + UpdateHTTPDNSClusterDefault(context.Context, *UpdateHTTPDNSClusterDefaultRequest) (*RPCSuccess, error) + ListHTTPDNSNodesWithClusterId(context.Context, *ListHTTPDNSNodesWithClusterIdRequest) (*ListHTTPDNSNodesWithClusterIdResponse, error) +} + +// UnimplementedHTTPDNSClusterServiceServer 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 UnimplementedHTTPDNSClusterServiceServer struct{} + +func (UnimplementedHTTPDNSClusterServiceServer) CreateHTTPDNSCluster(context.Context, *CreateHTTPDNSClusterRequest) (*CreateHTTPDNSClusterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHTTPDNSCluster not implemented") +} +func (UnimplementedHTTPDNSClusterServiceServer) UpdateHTTPDNSCluster(context.Context, *UpdateHTTPDNSClusterRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSCluster not implemented") +} +func (UnimplementedHTTPDNSClusterServiceServer) DeleteHTTPDNSCluster(context.Context, *DeleteHTTPDNSClusterRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteHTTPDNSCluster not implemented") +} +func (UnimplementedHTTPDNSClusterServiceServer) FindHTTPDNSCluster(context.Context, *FindHTTPDNSClusterRequest) (*FindHTTPDNSClusterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindHTTPDNSCluster not implemented") +} +func (UnimplementedHTTPDNSClusterServiceServer) ListHTTPDNSClusters(context.Context, *ListHTTPDNSClustersRequest) (*ListHTTPDNSClustersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListHTTPDNSClusters not implemented") +} +func (UnimplementedHTTPDNSClusterServiceServer) FindAllHTTPDNSClusters(context.Context, *FindAllHTTPDNSClustersRequest) (*FindAllHTTPDNSClustersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindAllHTTPDNSClusters not implemented") +} +func (UnimplementedHTTPDNSClusterServiceServer) UpdateHTTPDNSClusterDefault(context.Context, *UpdateHTTPDNSClusterDefaultRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSClusterDefault not implemented") +} +func (UnimplementedHTTPDNSClusterServiceServer) ListHTTPDNSNodesWithClusterId(context.Context, *ListHTTPDNSNodesWithClusterIdRequest) (*ListHTTPDNSNodesWithClusterIdResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListHTTPDNSNodesWithClusterId not implemented") +} +func (UnimplementedHTTPDNSClusterServiceServer) testEmbeddedByValue() {} + +// UnsafeHTTPDNSClusterServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HTTPDNSClusterServiceServer will +// result in compilation errors. +type UnsafeHTTPDNSClusterServiceServer interface { + mustEmbedUnimplementedHTTPDNSClusterServiceServer() +} + +func RegisterHTTPDNSClusterServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSClusterServiceServer) { + // If the following call pancis, it indicates UnimplementedHTTPDNSClusterServiceServer 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(&HTTPDNSClusterService_ServiceDesc, srv) +} + +func _HTTPDNSClusterService_CreateHTTPDNSCluster_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateHTTPDNSClusterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSClusterServiceServer).CreateHTTPDNSCluster(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSClusterService_CreateHTTPDNSCluster_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSClusterServiceServer).CreateHTTPDNSCluster(ctx, req.(*CreateHTTPDNSClusterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSClusterService_UpdateHTTPDNSCluster_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSClusterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSClusterServiceServer).UpdateHTTPDNSCluster(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSClusterService_UpdateHTTPDNSCluster_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSClusterServiceServer).UpdateHTTPDNSCluster(ctx, req.(*UpdateHTTPDNSClusterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSClusterService_DeleteHTTPDNSCluster_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteHTTPDNSClusterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSClusterServiceServer).DeleteHTTPDNSCluster(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSClusterService_DeleteHTTPDNSCluster_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSClusterServiceServer).DeleteHTTPDNSCluster(ctx, req.(*DeleteHTTPDNSClusterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSClusterService_FindHTTPDNSCluster_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindHTTPDNSClusterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSClusterServiceServer).FindHTTPDNSCluster(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSClusterService_FindHTTPDNSCluster_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSClusterServiceServer).FindHTTPDNSCluster(ctx, req.(*FindHTTPDNSClusterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSClusterService_ListHTTPDNSClusters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListHTTPDNSClustersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSClusterServiceServer).ListHTTPDNSClusters(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSClusterService_ListHTTPDNSClusters_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSClusterServiceServer).ListHTTPDNSClusters(ctx, req.(*ListHTTPDNSClustersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSClusterService_FindAllHTTPDNSClusters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindAllHTTPDNSClustersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSClusterServiceServer).FindAllHTTPDNSClusters(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSClusterService_FindAllHTTPDNSClusters_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSClusterServiceServer).FindAllHTTPDNSClusters(ctx, req.(*FindAllHTTPDNSClustersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSClusterService_UpdateHTTPDNSClusterDefault_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSClusterDefaultRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSClusterServiceServer).UpdateHTTPDNSClusterDefault(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSClusterService_UpdateHTTPDNSClusterDefault_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSClusterServiceServer).UpdateHTTPDNSClusterDefault(ctx, req.(*UpdateHTTPDNSClusterDefaultRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSClusterService_ListHTTPDNSNodesWithClusterId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListHTTPDNSNodesWithClusterIdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSClusterServiceServer).ListHTTPDNSNodesWithClusterId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSClusterService_ListHTTPDNSNodesWithClusterId_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSClusterServiceServer).ListHTTPDNSNodesWithClusterId(ctx, req.(*ListHTTPDNSNodesWithClusterIdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HTTPDNSClusterService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSClusterService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HTTPDNSClusterService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.HTTPDNSClusterService", + HandlerType: (*HTTPDNSClusterServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "createHTTPDNSCluster", + Handler: _HTTPDNSClusterService_CreateHTTPDNSCluster_Handler, + }, + { + MethodName: "updateHTTPDNSCluster", + Handler: _HTTPDNSClusterService_UpdateHTTPDNSCluster_Handler, + }, + { + MethodName: "deleteHTTPDNSCluster", + Handler: _HTTPDNSClusterService_DeleteHTTPDNSCluster_Handler, + }, + { + MethodName: "findHTTPDNSCluster", + Handler: _HTTPDNSClusterService_FindHTTPDNSCluster_Handler, + }, + { + MethodName: "listHTTPDNSClusters", + Handler: _HTTPDNSClusterService_ListHTTPDNSClusters_Handler, + }, + { + MethodName: "findAllHTTPDNSClusters", + Handler: _HTTPDNSClusterService_FindAllHTTPDNSClusters_Handler, + }, + { + MethodName: "updateHTTPDNSClusterDefault", + Handler: _HTTPDNSClusterService_UpdateHTTPDNSClusterDefault_Handler, + }, + { + MethodName: "listHTTPDNSNodesWithClusterId", + Handler: _HTTPDNSClusterService_ListHTTPDNSNodesWithClusterId_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service_httpdns_cluster.proto", +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_domain.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_domain.pb.go new file mode 100644 index 0000000..3adb6ae --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_domain.pb.go @@ -0,0 +1,456 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: service_httpdns_domain.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 CreateHTTPDNSDomainRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppDbId int64 `protobuf:"varint,1,opt,name=appDbId,proto3" json:"appDbId,omitempty"` + Domain string `protobuf:"bytes,2,opt,name=domain,proto3" json:"domain,omitempty"` + IsOn bool `protobuf:"varint,3,opt,name=isOn,proto3" json:"isOn,omitempty"` +} + +func (x *CreateHTTPDNSDomainRequest) Reset() { + *x = CreateHTTPDNSDomainRequest{} + mi := &file_service_httpdns_domain_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSDomainRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSDomainRequest) ProtoMessage() {} + +func (x *CreateHTTPDNSDomainRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_domain_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 CreateHTTPDNSDomainRequest.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSDomainRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_domain_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateHTTPDNSDomainRequest) GetAppDbId() int64 { + if x != nil { + return x.AppDbId + } + return 0 +} + +func (x *CreateHTTPDNSDomainRequest) GetDomain() string { + if x != nil { + return x.Domain + } + return "" +} + +func (x *CreateHTTPDNSDomainRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +type CreateHTTPDNSDomainResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DomainId int64 `protobuf:"varint,1,opt,name=domainId,proto3" json:"domainId,omitempty"` +} + +func (x *CreateHTTPDNSDomainResponse) Reset() { + *x = CreateHTTPDNSDomainResponse{} + mi := &file_service_httpdns_domain_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSDomainResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSDomainResponse) ProtoMessage() {} + +func (x *CreateHTTPDNSDomainResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_domain_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 CreateHTTPDNSDomainResponse.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSDomainResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_domain_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateHTTPDNSDomainResponse) GetDomainId() int64 { + if x != nil { + return x.DomainId + } + return 0 +} + +type DeleteHTTPDNSDomainRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DomainId int64 `protobuf:"varint,1,opt,name=domainId,proto3" json:"domainId,omitempty"` +} + +func (x *DeleteHTTPDNSDomainRequest) Reset() { + *x = DeleteHTTPDNSDomainRequest{} + mi := &file_service_httpdns_domain_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteHTTPDNSDomainRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteHTTPDNSDomainRequest) ProtoMessage() {} + +func (x *DeleteHTTPDNSDomainRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_domain_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 DeleteHTTPDNSDomainRequest.ProtoReflect.Descriptor instead. +func (*DeleteHTTPDNSDomainRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_domain_proto_rawDescGZIP(), []int{2} +} + +func (x *DeleteHTTPDNSDomainRequest) GetDomainId() int64 { + if x != nil { + return x.DomainId + } + return 0 +} + +type UpdateHTTPDNSDomainStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DomainId int64 `protobuf:"varint,1,opt,name=domainId,proto3" json:"domainId,omitempty"` + IsOn bool `protobuf:"varint,2,opt,name=isOn,proto3" json:"isOn,omitempty"` +} + +func (x *UpdateHTTPDNSDomainStatusRequest) Reset() { + *x = UpdateHTTPDNSDomainStatusRequest{} + mi := &file_service_httpdns_domain_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSDomainStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSDomainStatusRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSDomainStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_domain_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 UpdateHTTPDNSDomainStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSDomainStatusRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_domain_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateHTTPDNSDomainStatusRequest) GetDomainId() int64 { + if x != nil { + return x.DomainId + } + return 0 +} + +func (x *UpdateHTTPDNSDomainStatusRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +type ListHTTPDNSDomainsWithAppIdRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AppDbId int64 `protobuf:"varint,1,opt,name=appDbId,proto3" json:"appDbId,omitempty"` + Keyword string `protobuf:"bytes,2,opt,name=keyword,proto3" json:"keyword,omitempty"` +} + +func (x *ListHTTPDNSDomainsWithAppIdRequest) Reset() { + *x = ListHTTPDNSDomainsWithAppIdRequest{} + mi := &file_service_httpdns_domain_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSDomainsWithAppIdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSDomainsWithAppIdRequest) ProtoMessage() {} + +func (x *ListHTTPDNSDomainsWithAppIdRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_domain_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 ListHTTPDNSDomainsWithAppIdRequest.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSDomainsWithAppIdRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_domain_proto_rawDescGZIP(), []int{4} +} + +func (x *ListHTTPDNSDomainsWithAppIdRequest) GetAppDbId() int64 { + if x != nil { + return x.AppDbId + } + return 0 +} + +func (x *ListHTTPDNSDomainsWithAppIdRequest) GetKeyword() string { + if x != nil { + return x.Keyword + } + return "" +} + +type ListHTTPDNSDomainsWithAppIdResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Domains []*HTTPDNSDomain `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains,omitempty"` +} + +func (x *ListHTTPDNSDomainsWithAppIdResponse) Reset() { + *x = ListHTTPDNSDomainsWithAppIdResponse{} + mi := &file_service_httpdns_domain_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSDomainsWithAppIdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSDomainsWithAppIdResponse) ProtoMessage() {} + +func (x *ListHTTPDNSDomainsWithAppIdResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_domain_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 ListHTTPDNSDomainsWithAppIdResponse.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSDomainsWithAppIdResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_domain_proto_rawDescGZIP(), []int{5} +} + +func (x *ListHTTPDNSDomainsWithAppIdResponse) GetDomains() []*HTTPDNSDomain { + if x != nil { + return x.Domains + } + return nil +} + +var File_service_httpdns_domain_proto protoreflect.FileDescriptor + +var file_service_httpdns_domain_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, + 0x73, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, + 0x70, 0x62, 0x1a, 0x21, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x72, 0x70, + 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x62, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, + 0x69, 0x73, 0x4f, 0x6e, 0x22, 0x39, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, + 0x38, 0x0a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x08, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0x52, 0x0a, 0x20, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x08, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x22, 0x58, 0x0a, + 0x22, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x61, 0x70, 0x70, 0x44, 0x62, 0x49, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x52, 0x0a, 0x23, 0x4c, 0x69, 0x73, 0x74, 0x48, + 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, + 0x68, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, + 0x0a, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x32, 0xf8, 0x02, 0x0a, 0x14, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x56, 0x0a, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x2e, 0x70, 0x62, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x62, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x13, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x12, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, + 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x51, 0x0a, 0x19, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, + 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x24, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, + 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x6e, 0x0a, 0x1b, 0x6c, 0x69, 0x73, 0x74, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, + 0x41, 0x70, 0x70, 0x49, 0x64, 0x12, 0x26, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, + 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, + 0x68, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, + 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x57, 0x69, 0x74, 0x68, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_service_httpdns_domain_proto_rawDescOnce sync.Once + file_service_httpdns_domain_proto_rawDescData = file_service_httpdns_domain_proto_rawDesc +) + +func file_service_httpdns_domain_proto_rawDescGZIP() []byte { + file_service_httpdns_domain_proto_rawDescOnce.Do(func() { + file_service_httpdns_domain_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_httpdns_domain_proto_rawDescData) + }) + return file_service_httpdns_domain_proto_rawDescData +} + +var file_service_httpdns_domain_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_service_httpdns_domain_proto_goTypes = []any{ + (*CreateHTTPDNSDomainRequest)(nil), // 0: pb.CreateHTTPDNSDomainRequest + (*CreateHTTPDNSDomainResponse)(nil), // 1: pb.CreateHTTPDNSDomainResponse + (*DeleteHTTPDNSDomainRequest)(nil), // 2: pb.DeleteHTTPDNSDomainRequest + (*UpdateHTTPDNSDomainStatusRequest)(nil), // 3: pb.UpdateHTTPDNSDomainStatusRequest + (*ListHTTPDNSDomainsWithAppIdRequest)(nil), // 4: pb.ListHTTPDNSDomainsWithAppIdRequest + (*ListHTTPDNSDomainsWithAppIdResponse)(nil), // 5: pb.ListHTTPDNSDomainsWithAppIdResponse + (*HTTPDNSDomain)(nil), // 6: pb.HTTPDNSDomain + (*RPCSuccess)(nil), // 7: pb.RPCSuccess +} +var file_service_httpdns_domain_proto_depIdxs = []int32{ + 6, // 0: pb.ListHTTPDNSDomainsWithAppIdResponse.domains:type_name -> pb.HTTPDNSDomain + 0, // 1: pb.HTTPDNSDomainService.createHTTPDNSDomain:input_type -> pb.CreateHTTPDNSDomainRequest + 2, // 2: pb.HTTPDNSDomainService.deleteHTTPDNSDomain:input_type -> pb.DeleteHTTPDNSDomainRequest + 3, // 3: pb.HTTPDNSDomainService.updateHTTPDNSDomainStatus:input_type -> pb.UpdateHTTPDNSDomainStatusRequest + 4, // 4: pb.HTTPDNSDomainService.listHTTPDNSDomainsWithAppId:input_type -> pb.ListHTTPDNSDomainsWithAppIdRequest + 1, // 5: pb.HTTPDNSDomainService.createHTTPDNSDomain:output_type -> pb.CreateHTTPDNSDomainResponse + 7, // 6: pb.HTTPDNSDomainService.deleteHTTPDNSDomain:output_type -> pb.RPCSuccess + 7, // 7: pb.HTTPDNSDomainService.updateHTTPDNSDomainStatus:output_type -> pb.RPCSuccess + 5, // 8: pb.HTTPDNSDomainService.listHTTPDNSDomainsWithAppId:output_type -> pb.ListHTTPDNSDomainsWithAppIdResponse + 5, // [5:9] is the sub-list for method output_type + 1, // [1:5] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_service_httpdns_domain_proto_init() } +func file_service_httpdns_domain_proto_init() { + if File_service_httpdns_domain_proto != nil { + return + } + file_models_model_httpdns_domain_proto_init() + file_models_rpc_messages_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_service_httpdns_domain_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_service_httpdns_domain_proto_goTypes, + DependencyIndexes: file_service_httpdns_domain_proto_depIdxs, + MessageInfos: file_service_httpdns_domain_proto_msgTypes, + }.Build() + File_service_httpdns_domain_proto = out.File + file_service_httpdns_domain_proto_rawDesc = nil + file_service_httpdns_domain_proto_goTypes = nil + file_service_httpdns_domain_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_domain_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_domain_grpc.pb.go new file mode 100644 index 0000000..d04f113 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_domain_grpc.pb.go @@ -0,0 +1,233 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: service_httpdns_domain.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 ( + HTTPDNSDomainService_CreateHTTPDNSDomain_FullMethodName = "/pb.HTTPDNSDomainService/createHTTPDNSDomain" + HTTPDNSDomainService_DeleteHTTPDNSDomain_FullMethodName = "/pb.HTTPDNSDomainService/deleteHTTPDNSDomain" + HTTPDNSDomainService_UpdateHTTPDNSDomainStatus_FullMethodName = "/pb.HTTPDNSDomainService/updateHTTPDNSDomainStatus" + HTTPDNSDomainService_ListHTTPDNSDomainsWithAppId_FullMethodName = "/pb.HTTPDNSDomainService/listHTTPDNSDomainsWithAppId" +) + +// HTTPDNSDomainServiceClient is the client API for HTTPDNSDomainService 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. +type HTTPDNSDomainServiceClient interface { + CreateHTTPDNSDomain(ctx context.Context, in *CreateHTTPDNSDomainRequest, opts ...grpc.CallOption) (*CreateHTTPDNSDomainResponse, error) + DeleteHTTPDNSDomain(ctx context.Context, in *DeleteHTTPDNSDomainRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + UpdateHTTPDNSDomainStatus(ctx context.Context, in *UpdateHTTPDNSDomainStatusRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + ListHTTPDNSDomainsWithAppId(ctx context.Context, in *ListHTTPDNSDomainsWithAppIdRequest, opts ...grpc.CallOption) (*ListHTTPDNSDomainsWithAppIdResponse, error) +} + +type hTTPDNSDomainServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHTTPDNSDomainServiceClient(cc grpc.ClientConnInterface) HTTPDNSDomainServiceClient { + return &hTTPDNSDomainServiceClient{cc} +} + +func (c *hTTPDNSDomainServiceClient) CreateHTTPDNSDomain(ctx context.Context, in *CreateHTTPDNSDomainRequest, opts ...grpc.CallOption) (*CreateHTTPDNSDomainResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateHTTPDNSDomainResponse) + err := c.cc.Invoke(ctx, HTTPDNSDomainService_CreateHTTPDNSDomain_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSDomainServiceClient) DeleteHTTPDNSDomain(ctx context.Context, in *DeleteHTTPDNSDomainRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSDomainService_DeleteHTTPDNSDomain_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSDomainServiceClient) UpdateHTTPDNSDomainStatus(ctx context.Context, in *UpdateHTTPDNSDomainStatusRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSDomainService_UpdateHTTPDNSDomainStatus_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSDomainServiceClient) ListHTTPDNSDomainsWithAppId(ctx context.Context, in *ListHTTPDNSDomainsWithAppIdRequest, opts ...grpc.CallOption) (*ListHTTPDNSDomainsWithAppIdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListHTTPDNSDomainsWithAppIdResponse) + err := c.cc.Invoke(ctx, HTTPDNSDomainService_ListHTTPDNSDomainsWithAppId_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HTTPDNSDomainServiceServer is the server API for HTTPDNSDomainService service. +// All implementations should embed UnimplementedHTTPDNSDomainServiceServer +// for forward compatibility. +type HTTPDNSDomainServiceServer interface { + CreateHTTPDNSDomain(context.Context, *CreateHTTPDNSDomainRequest) (*CreateHTTPDNSDomainResponse, error) + DeleteHTTPDNSDomain(context.Context, *DeleteHTTPDNSDomainRequest) (*RPCSuccess, error) + UpdateHTTPDNSDomainStatus(context.Context, *UpdateHTTPDNSDomainStatusRequest) (*RPCSuccess, error) + ListHTTPDNSDomainsWithAppId(context.Context, *ListHTTPDNSDomainsWithAppIdRequest) (*ListHTTPDNSDomainsWithAppIdResponse, error) +} + +// UnimplementedHTTPDNSDomainServiceServer 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 UnimplementedHTTPDNSDomainServiceServer struct{} + +func (UnimplementedHTTPDNSDomainServiceServer) CreateHTTPDNSDomain(context.Context, *CreateHTTPDNSDomainRequest) (*CreateHTTPDNSDomainResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHTTPDNSDomain not implemented") +} +func (UnimplementedHTTPDNSDomainServiceServer) DeleteHTTPDNSDomain(context.Context, *DeleteHTTPDNSDomainRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteHTTPDNSDomain not implemented") +} +func (UnimplementedHTTPDNSDomainServiceServer) UpdateHTTPDNSDomainStatus(context.Context, *UpdateHTTPDNSDomainStatusRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSDomainStatus not implemented") +} +func (UnimplementedHTTPDNSDomainServiceServer) ListHTTPDNSDomainsWithAppId(context.Context, *ListHTTPDNSDomainsWithAppIdRequest) (*ListHTTPDNSDomainsWithAppIdResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListHTTPDNSDomainsWithAppId not implemented") +} +func (UnimplementedHTTPDNSDomainServiceServer) testEmbeddedByValue() {} + +// UnsafeHTTPDNSDomainServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HTTPDNSDomainServiceServer will +// result in compilation errors. +type UnsafeHTTPDNSDomainServiceServer interface { + mustEmbedUnimplementedHTTPDNSDomainServiceServer() +} + +func RegisterHTTPDNSDomainServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSDomainServiceServer) { + // If the following call pancis, it indicates UnimplementedHTTPDNSDomainServiceServer 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(&HTTPDNSDomainService_ServiceDesc, srv) +} + +func _HTTPDNSDomainService_CreateHTTPDNSDomain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateHTTPDNSDomainRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSDomainServiceServer).CreateHTTPDNSDomain(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSDomainService_CreateHTTPDNSDomain_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSDomainServiceServer).CreateHTTPDNSDomain(ctx, req.(*CreateHTTPDNSDomainRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSDomainService_DeleteHTTPDNSDomain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteHTTPDNSDomainRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSDomainServiceServer).DeleteHTTPDNSDomain(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSDomainService_DeleteHTTPDNSDomain_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSDomainServiceServer).DeleteHTTPDNSDomain(ctx, req.(*DeleteHTTPDNSDomainRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSDomainService_UpdateHTTPDNSDomainStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSDomainStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSDomainServiceServer).UpdateHTTPDNSDomainStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSDomainService_UpdateHTTPDNSDomainStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSDomainServiceServer).UpdateHTTPDNSDomainStatus(ctx, req.(*UpdateHTTPDNSDomainStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSDomainService_ListHTTPDNSDomainsWithAppId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListHTTPDNSDomainsWithAppIdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSDomainServiceServer).ListHTTPDNSDomainsWithAppId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSDomainService_ListHTTPDNSDomainsWithAppId_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSDomainServiceServer).ListHTTPDNSDomainsWithAppId(ctx, req.(*ListHTTPDNSDomainsWithAppIdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HTTPDNSDomainService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSDomainService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HTTPDNSDomainService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.HTTPDNSDomainService", + HandlerType: (*HTTPDNSDomainServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "createHTTPDNSDomain", + Handler: _HTTPDNSDomainService_CreateHTTPDNSDomain_Handler, + }, + { + MethodName: "deleteHTTPDNSDomain", + Handler: _HTTPDNSDomainService_DeleteHTTPDNSDomain_Handler, + }, + { + MethodName: "updateHTTPDNSDomainStatus", + Handler: _HTTPDNSDomainService_UpdateHTTPDNSDomainStatus_Handler, + }, + { + MethodName: "listHTTPDNSDomainsWithAppId", + Handler: _HTTPDNSDomainService_ListHTTPDNSDomainsWithAppId_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service_httpdns_domain.proto", +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_node.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_node.pb.go new file mode 100644 index 0000000..8c0e5b3 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_node.pb.go @@ -0,0 +1,682 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: service_httpdns_node.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 CreateHTTPDNSNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + InstallDir string `protobuf:"bytes,3,opt,name=installDir,proto3" json:"installDir,omitempty"` + IsOn bool `protobuf:"varint,4,opt,name=isOn,proto3" json:"isOn,omitempty"` +} + +func (x *CreateHTTPDNSNodeRequest) Reset() { + *x = CreateHTTPDNSNodeRequest{} + mi := &file_service_httpdns_node_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSNodeRequest) ProtoMessage() {} + +func (x *CreateHTTPDNSNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_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 CreateHTTPDNSNodeRequest.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSNodeRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateHTTPDNSNodeRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +func (x *CreateHTTPDNSNodeRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateHTTPDNSNodeRequest) GetInstallDir() string { + if x != nil { + return x.InstallDir + } + return "" +} + +func (x *CreateHTTPDNSNodeRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +type CreateHTTPDNSNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId int64 `protobuf:"varint,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` +} + +func (x *CreateHTTPDNSNodeResponse) Reset() { + *x = CreateHTTPDNSNodeResponse{} + mi := &file_service_httpdns_node_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSNodeResponse) ProtoMessage() {} + +func (x *CreateHTTPDNSNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_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 CreateHTTPDNSNodeResponse.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSNodeResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateHTTPDNSNodeResponse) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +type UpdateHTTPDNSNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId int64 `protobuf:"varint,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + InstallDir string `protobuf:"bytes,3,opt,name=installDir,proto3" json:"installDir,omitempty"` + IsOn bool `protobuf:"varint,4,opt,name=isOn,proto3" json:"isOn,omitempty"` +} + +func (x *UpdateHTTPDNSNodeRequest) Reset() { + *x = UpdateHTTPDNSNodeRequest{} + mi := &file_service_httpdns_node_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSNodeRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_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 UpdateHTTPDNSNodeRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSNodeRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateHTTPDNSNodeRequest) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *UpdateHTTPDNSNodeRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateHTTPDNSNodeRequest) GetInstallDir() string { + if x != nil { + return x.InstallDir + } + return "" +} + +func (x *UpdateHTTPDNSNodeRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +type DeleteHTTPDNSNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId int64 `protobuf:"varint,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` +} + +func (x *DeleteHTTPDNSNodeRequest) Reset() { + *x = DeleteHTTPDNSNodeRequest{} + mi := &file_service_httpdns_node_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteHTTPDNSNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteHTTPDNSNodeRequest) ProtoMessage() {} + +func (x *DeleteHTTPDNSNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_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 DeleteHTTPDNSNodeRequest.ProtoReflect.Descriptor instead. +func (*DeleteHTTPDNSNodeRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{3} +} + +func (x *DeleteHTTPDNSNodeRequest) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +type FindHTTPDNSNodeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId int64 `protobuf:"varint,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` +} + +func (x *FindHTTPDNSNodeRequest) Reset() { + *x = FindHTTPDNSNodeRequest{} + mi := &file_service_httpdns_node_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindHTTPDNSNodeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindHTTPDNSNodeRequest) ProtoMessage() {} + +func (x *FindHTTPDNSNodeRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_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 FindHTTPDNSNodeRequest.ProtoReflect.Descriptor instead. +func (*FindHTTPDNSNodeRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{4} +} + +func (x *FindHTTPDNSNodeRequest) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +type FindHTTPDNSNodeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node *HTTPDNSNode `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` +} + +func (x *FindHTTPDNSNodeResponse) Reset() { + *x = FindHTTPDNSNodeResponse{} + mi := &file_service_httpdns_node_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FindHTTPDNSNodeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindHTTPDNSNodeResponse) ProtoMessage() {} + +func (x *FindHTTPDNSNodeResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_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 FindHTTPDNSNodeResponse.ProtoReflect.Descriptor instead. +func (*FindHTTPDNSNodeResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{5} +} + +func (x *FindHTTPDNSNodeResponse) GetNode() *HTTPDNSNode { + if x != nil { + return x.Node + } + return nil +} + +type ListHTTPDNSNodesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` +} + +func (x *ListHTTPDNSNodesRequest) Reset() { + *x = ListHTTPDNSNodesRequest{} + mi := &file_service_httpdns_node_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSNodesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSNodesRequest) ProtoMessage() {} + +func (x *ListHTTPDNSNodesRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_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 ListHTTPDNSNodesRequest.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSNodesRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{6} +} + +func (x *ListHTTPDNSNodesRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +type ListHTTPDNSNodesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*HTTPDNSNode `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` +} + +func (x *ListHTTPDNSNodesResponse) Reset() { + *x = ListHTTPDNSNodesResponse{} + mi := &file_service_httpdns_node_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSNodesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSNodesResponse) ProtoMessage() {} + +func (x *ListHTTPDNSNodesResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_proto_msgTypes[7] + 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 ListHTTPDNSNodesResponse.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSNodesResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{7} +} + +func (x *ListHTTPDNSNodesResponse) GetNodes() []*HTTPDNSNode { + if x != nil { + return x.Nodes + } + return nil +} + +type UpdateHTTPDNSNodeStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId int64 `protobuf:"varint,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + IsUp bool `protobuf:"varint,2,opt,name=isUp,proto3" json:"isUp,omitempty"` + IsInstalled bool `protobuf:"varint,3,opt,name=isInstalled,proto3" json:"isInstalled,omitempty"` + IsActive bool `protobuf:"varint,4,opt,name=isActive,proto3" json:"isActive,omitempty"` + StatusJSON []byte `protobuf:"bytes,5,opt,name=statusJSON,proto3" json:"statusJSON,omitempty"` + InstallStatusJSON []byte `protobuf:"bytes,6,opt,name=installStatusJSON,proto3" json:"installStatusJSON,omitempty"` +} + +func (x *UpdateHTTPDNSNodeStatusRequest) Reset() { + *x = UpdateHTTPDNSNodeStatusRequest{} + mi := &file_service_httpdns_node_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSNodeStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSNodeStatusRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSNodeStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_node_proto_msgTypes[8] + 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 UpdateHTTPDNSNodeStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSNodeStatusRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_node_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateHTTPDNSNodeStatusRequest) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *UpdateHTTPDNSNodeStatusRequest) GetIsUp() bool { + if x != nil { + return x.IsUp + } + return false +} + +func (x *UpdateHTTPDNSNodeStatusRequest) GetIsInstalled() bool { + if x != nil { + return x.IsInstalled + } + return false +} + +func (x *UpdateHTTPDNSNodeStatusRequest) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +func (x *UpdateHTTPDNSNodeStatusRequest) GetStatusJSON() []byte { + if x != nil { + return x.StatusJSON + } + return nil +} + +func (x *UpdateHTTPDNSNodeStatusRequest) GetInstallStatusJSON() []byte { + if x != nil { + return x.InstallStatusJSON + } + return nil +} + +var File_service_httpdns_node_proto protoreflect.FileDescriptor + +var file_service_httpdns_node_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, + 0x73, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, + 0x1a, 0x1f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x19, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x5f, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x80, 0x01, 0x0a, + 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x69, + 0x73, 0x4f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x22, + 0x33, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x22, 0x7a, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x12, 0x12, 0x0a, 0x04, + 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, + 0x22, 0x32, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, + 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, + 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0x3e, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x23, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x37, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, + 0x41, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, + 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x6e, + 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, + 0x65, 0x73, 0x22, 0xd8, 0x01, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, + 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x69, 0x73, 0x55, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x55, + 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, + 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x12, + 0x2c, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x32, 0xd6, 0x03, + 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x11, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x2e, 0x70, 0x62, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, + 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x41, 0x0a, 0x11, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1c, + 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, + 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4a, 0x0a, 0x0f, + 0x66, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x12, + 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x62, + 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x10, 0x6c, 0x69, 0x73, 0x74, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x70, + 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x17, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x22, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_service_httpdns_node_proto_rawDescOnce sync.Once + file_service_httpdns_node_proto_rawDescData = file_service_httpdns_node_proto_rawDesc +) + +func file_service_httpdns_node_proto_rawDescGZIP() []byte { + file_service_httpdns_node_proto_rawDescOnce.Do(func() { + file_service_httpdns_node_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_httpdns_node_proto_rawDescData) + }) + return file_service_httpdns_node_proto_rawDescData +} + +var file_service_httpdns_node_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_service_httpdns_node_proto_goTypes = []any{ + (*CreateHTTPDNSNodeRequest)(nil), // 0: pb.CreateHTTPDNSNodeRequest + (*CreateHTTPDNSNodeResponse)(nil), // 1: pb.CreateHTTPDNSNodeResponse + (*UpdateHTTPDNSNodeRequest)(nil), // 2: pb.UpdateHTTPDNSNodeRequest + (*DeleteHTTPDNSNodeRequest)(nil), // 3: pb.DeleteHTTPDNSNodeRequest + (*FindHTTPDNSNodeRequest)(nil), // 4: pb.FindHTTPDNSNodeRequest + (*FindHTTPDNSNodeResponse)(nil), // 5: pb.FindHTTPDNSNodeResponse + (*ListHTTPDNSNodesRequest)(nil), // 6: pb.ListHTTPDNSNodesRequest + (*ListHTTPDNSNodesResponse)(nil), // 7: pb.ListHTTPDNSNodesResponse + (*UpdateHTTPDNSNodeStatusRequest)(nil), // 8: pb.UpdateHTTPDNSNodeStatusRequest + (*HTTPDNSNode)(nil), // 9: pb.HTTPDNSNode + (*RPCSuccess)(nil), // 10: pb.RPCSuccess +} +var file_service_httpdns_node_proto_depIdxs = []int32{ + 9, // 0: pb.FindHTTPDNSNodeResponse.node:type_name -> pb.HTTPDNSNode + 9, // 1: pb.ListHTTPDNSNodesResponse.nodes:type_name -> pb.HTTPDNSNode + 0, // 2: pb.HTTPDNSNodeService.createHTTPDNSNode:input_type -> pb.CreateHTTPDNSNodeRequest + 2, // 3: pb.HTTPDNSNodeService.updateHTTPDNSNode:input_type -> pb.UpdateHTTPDNSNodeRequest + 3, // 4: pb.HTTPDNSNodeService.deleteHTTPDNSNode:input_type -> pb.DeleteHTTPDNSNodeRequest + 4, // 5: pb.HTTPDNSNodeService.findHTTPDNSNode:input_type -> pb.FindHTTPDNSNodeRequest + 6, // 6: pb.HTTPDNSNodeService.listHTTPDNSNodes:input_type -> pb.ListHTTPDNSNodesRequest + 8, // 7: pb.HTTPDNSNodeService.updateHTTPDNSNodeStatus:input_type -> pb.UpdateHTTPDNSNodeStatusRequest + 1, // 8: pb.HTTPDNSNodeService.createHTTPDNSNode:output_type -> pb.CreateHTTPDNSNodeResponse + 10, // 9: pb.HTTPDNSNodeService.updateHTTPDNSNode:output_type -> pb.RPCSuccess + 10, // 10: pb.HTTPDNSNodeService.deleteHTTPDNSNode:output_type -> pb.RPCSuccess + 5, // 11: pb.HTTPDNSNodeService.findHTTPDNSNode:output_type -> pb.FindHTTPDNSNodeResponse + 7, // 12: pb.HTTPDNSNodeService.listHTTPDNSNodes:output_type -> pb.ListHTTPDNSNodesResponse + 10, // 13: pb.HTTPDNSNodeService.updateHTTPDNSNodeStatus:output_type -> pb.RPCSuccess + 8, // [8:14] is the sub-list for method output_type + 2, // [2:8] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_service_httpdns_node_proto_init() } +func file_service_httpdns_node_proto_init() { + if File_service_httpdns_node_proto != nil { + return + } + file_models_model_httpdns_node_proto_init() + file_models_rpc_messages_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_service_httpdns_node_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_service_httpdns_node_proto_goTypes, + DependencyIndexes: file_service_httpdns_node_proto_depIdxs, + MessageInfos: file_service_httpdns_node_proto_msgTypes, + }.Build() + File_service_httpdns_node_proto = out.File + file_service_httpdns_node_proto_rawDesc = nil + file_service_httpdns_node_proto_goTypes = nil + file_service_httpdns_node_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_node_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_node_grpc.pb.go new file mode 100644 index 0000000..51b3cd5 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_node_grpc.pb.go @@ -0,0 +1,309 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: service_httpdns_node.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 ( + HTTPDNSNodeService_CreateHTTPDNSNode_FullMethodName = "/pb.HTTPDNSNodeService/createHTTPDNSNode" + HTTPDNSNodeService_UpdateHTTPDNSNode_FullMethodName = "/pb.HTTPDNSNodeService/updateHTTPDNSNode" + HTTPDNSNodeService_DeleteHTTPDNSNode_FullMethodName = "/pb.HTTPDNSNodeService/deleteHTTPDNSNode" + HTTPDNSNodeService_FindHTTPDNSNode_FullMethodName = "/pb.HTTPDNSNodeService/findHTTPDNSNode" + HTTPDNSNodeService_ListHTTPDNSNodes_FullMethodName = "/pb.HTTPDNSNodeService/listHTTPDNSNodes" + HTTPDNSNodeService_UpdateHTTPDNSNodeStatus_FullMethodName = "/pb.HTTPDNSNodeService/updateHTTPDNSNodeStatus" +) + +// HTTPDNSNodeServiceClient is the client API for HTTPDNSNodeService 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. +type HTTPDNSNodeServiceClient interface { + CreateHTTPDNSNode(ctx context.Context, in *CreateHTTPDNSNodeRequest, opts ...grpc.CallOption) (*CreateHTTPDNSNodeResponse, error) + UpdateHTTPDNSNode(ctx context.Context, in *UpdateHTTPDNSNodeRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + DeleteHTTPDNSNode(ctx context.Context, in *DeleteHTTPDNSNodeRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + FindHTTPDNSNode(ctx context.Context, in *FindHTTPDNSNodeRequest, opts ...grpc.CallOption) (*FindHTTPDNSNodeResponse, error) + ListHTTPDNSNodes(ctx context.Context, in *ListHTTPDNSNodesRequest, opts ...grpc.CallOption) (*ListHTTPDNSNodesResponse, error) + UpdateHTTPDNSNodeStatus(ctx context.Context, in *UpdateHTTPDNSNodeStatusRequest, opts ...grpc.CallOption) (*RPCSuccess, error) +} + +type hTTPDNSNodeServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHTTPDNSNodeServiceClient(cc grpc.ClientConnInterface) HTTPDNSNodeServiceClient { + return &hTTPDNSNodeServiceClient{cc} +} + +func (c *hTTPDNSNodeServiceClient) CreateHTTPDNSNode(ctx context.Context, in *CreateHTTPDNSNodeRequest, opts ...grpc.CallOption) (*CreateHTTPDNSNodeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateHTTPDNSNodeResponse) + err := c.cc.Invoke(ctx, HTTPDNSNodeService_CreateHTTPDNSNode_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSNodeServiceClient) UpdateHTTPDNSNode(ctx context.Context, in *UpdateHTTPDNSNodeRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSNodeService_UpdateHTTPDNSNode_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSNodeServiceClient) DeleteHTTPDNSNode(ctx context.Context, in *DeleteHTTPDNSNodeRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSNodeService_DeleteHTTPDNSNode_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSNodeServiceClient) FindHTTPDNSNode(ctx context.Context, in *FindHTTPDNSNodeRequest, opts ...grpc.CallOption) (*FindHTTPDNSNodeResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(FindHTTPDNSNodeResponse) + err := c.cc.Invoke(ctx, HTTPDNSNodeService_FindHTTPDNSNode_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSNodeServiceClient) ListHTTPDNSNodes(ctx context.Context, in *ListHTTPDNSNodesRequest, opts ...grpc.CallOption) (*ListHTTPDNSNodesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListHTTPDNSNodesResponse) + err := c.cc.Invoke(ctx, HTTPDNSNodeService_ListHTTPDNSNodes_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSNodeServiceClient) UpdateHTTPDNSNodeStatus(ctx context.Context, in *UpdateHTTPDNSNodeStatusRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSNodeService_UpdateHTTPDNSNodeStatus_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HTTPDNSNodeServiceServer is the server API for HTTPDNSNodeService service. +// All implementations should embed UnimplementedHTTPDNSNodeServiceServer +// for forward compatibility. +type HTTPDNSNodeServiceServer interface { + CreateHTTPDNSNode(context.Context, *CreateHTTPDNSNodeRequest) (*CreateHTTPDNSNodeResponse, error) + UpdateHTTPDNSNode(context.Context, *UpdateHTTPDNSNodeRequest) (*RPCSuccess, error) + DeleteHTTPDNSNode(context.Context, *DeleteHTTPDNSNodeRequest) (*RPCSuccess, error) + FindHTTPDNSNode(context.Context, *FindHTTPDNSNodeRequest) (*FindHTTPDNSNodeResponse, error) + ListHTTPDNSNodes(context.Context, *ListHTTPDNSNodesRequest) (*ListHTTPDNSNodesResponse, error) + UpdateHTTPDNSNodeStatus(context.Context, *UpdateHTTPDNSNodeStatusRequest) (*RPCSuccess, error) +} + +// UnimplementedHTTPDNSNodeServiceServer 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 UnimplementedHTTPDNSNodeServiceServer struct{} + +func (UnimplementedHTTPDNSNodeServiceServer) CreateHTTPDNSNode(context.Context, *CreateHTTPDNSNodeRequest) (*CreateHTTPDNSNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHTTPDNSNode not implemented") +} +func (UnimplementedHTTPDNSNodeServiceServer) UpdateHTTPDNSNode(context.Context, *UpdateHTTPDNSNodeRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSNode not implemented") +} +func (UnimplementedHTTPDNSNodeServiceServer) DeleteHTTPDNSNode(context.Context, *DeleteHTTPDNSNodeRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteHTTPDNSNode not implemented") +} +func (UnimplementedHTTPDNSNodeServiceServer) FindHTTPDNSNode(context.Context, *FindHTTPDNSNodeRequest) (*FindHTTPDNSNodeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindHTTPDNSNode not implemented") +} +func (UnimplementedHTTPDNSNodeServiceServer) ListHTTPDNSNodes(context.Context, *ListHTTPDNSNodesRequest) (*ListHTTPDNSNodesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListHTTPDNSNodes not implemented") +} +func (UnimplementedHTTPDNSNodeServiceServer) UpdateHTTPDNSNodeStatus(context.Context, *UpdateHTTPDNSNodeStatusRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSNodeStatus not implemented") +} +func (UnimplementedHTTPDNSNodeServiceServer) testEmbeddedByValue() {} + +// UnsafeHTTPDNSNodeServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HTTPDNSNodeServiceServer will +// result in compilation errors. +type UnsafeHTTPDNSNodeServiceServer interface { + mustEmbedUnimplementedHTTPDNSNodeServiceServer() +} + +func RegisterHTTPDNSNodeServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSNodeServiceServer) { + // If the following call pancis, it indicates UnimplementedHTTPDNSNodeServiceServer 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(&HTTPDNSNodeService_ServiceDesc, srv) +} + +func _HTTPDNSNodeService_CreateHTTPDNSNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateHTTPDNSNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSNodeServiceServer).CreateHTTPDNSNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSNodeService_CreateHTTPDNSNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSNodeServiceServer).CreateHTTPDNSNode(ctx, req.(*CreateHTTPDNSNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSNodeService_UpdateHTTPDNSNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSNodeServiceServer).UpdateHTTPDNSNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSNodeService_UpdateHTTPDNSNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSNodeServiceServer).UpdateHTTPDNSNode(ctx, req.(*UpdateHTTPDNSNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSNodeService_DeleteHTTPDNSNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteHTTPDNSNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSNodeServiceServer).DeleteHTTPDNSNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSNodeService_DeleteHTTPDNSNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSNodeServiceServer).DeleteHTTPDNSNode(ctx, req.(*DeleteHTTPDNSNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSNodeService_FindHTTPDNSNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindHTTPDNSNodeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSNodeServiceServer).FindHTTPDNSNode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSNodeService_FindHTTPDNSNode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSNodeServiceServer).FindHTTPDNSNode(ctx, req.(*FindHTTPDNSNodeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSNodeService_ListHTTPDNSNodes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListHTTPDNSNodesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSNodeServiceServer).ListHTTPDNSNodes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSNodeService_ListHTTPDNSNodes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSNodeServiceServer).ListHTTPDNSNodes(ctx, req.(*ListHTTPDNSNodesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSNodeService_UpdateHTTPDNSNodeStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSNodeStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSNodeServiceServer).UpdateHTTPDNSNodeStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSNodeService_UpdateHTTPDNSNodeStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSNodeServiceServer).UpdateHTTPDNSNodeStatus(ctx, req.(*UpdateHTTPDNSNodeStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HTTPDNSNodeService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSNodeService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HTTPDNSNodeService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.HTTPDNSNodeService", + HandlerType: (*HTTPDNSNodeServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "createHTTPDNSNode", + Handler: _HTTPDNSNodeService_CreateHTTPDNSNode_Handler, + }, + { + MethodName: "updateHTTPDNSNode", + Handler: _HTTPDNSNodeService_UpdateHTTPDNSNode_Handler, + }, + { + MethodName: "deleteHTTPDNSNode", + Handler: _HTTPDNSNodeService_DeleteHTTPDNSNode_Handler, + }, + { + MethodName: "findHTTPDNSNode", + Handler: _HTTPDNSNodeService_FindHTTPDNSNode_Handler, + }, + { + MethodName: "listHTTPDNSNodes", + Handler: _HTTPDNSNodeService_ListHTTPDNSNodes_Handler, + }, + { + MethodName: "updateHTTPDNSNodeStatus", + Handler: _HTTPDNSNodeService_UpdateHTTPDNSNodeStatus_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service_httpdns_node.proto", +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_rule.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_rule.pb.go new file mode 100644 index 0000000..1ac612c --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_rule.pb.go @@ -0,0 +1,492 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: service_httpdns_rule.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 CreateHTTPDNSCustomRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rule *HTTPDNSCustomRule `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"` +} + +func (x *CreateHTTPDNSCustomRuleRequest) Reset() { + *x = CreateHTTPDNSCustomRuleRequest{} + mi := &file_service_httpdns_rule_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSCustomRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSCustomRuleRequest) ProtoMessage() {} + +func (x *CreateHTTPDNSCustomRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_rule_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 CreateHTTPDNSCustomRuleRequest.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSCustomRuleRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_rule_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateHTTPDNSCustomRuleRequest) GetRule() *HTTPDNSCustomRule { + if x != nil { + return x.Rule + } + return nil +} + +type CreateHTTPDNSCustomRuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RuleId int64 `protobuf:"varint,1,opt,name=ruleId,proto3" json:"ruleId,omitempty"` +} + +func (x *CreateHTTPDNSCustomRuleResponse) Reset() { + *x = CreateHTTPDNSCustomRuleResponse{} + mi := &file_service_httpdns_rule_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSCustomRuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSCustomRuleResponse) ProtoMessage() {} + +func (x *CreateHTTPDNSCustomRuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_rule_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 CreateHTTPDNSCustomRuleResponse.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSCustomRuleResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_rule_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateHTTPDNSCustomRuleResponse) GetRuleId() int64 { + if x != nil { + return x.RuleId + } + return 0 +} + +type UpdateHTTPDNSCustomRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rule *HTTPDNSCustomRule `protobuf:"bytes,1,opt,name=rule,proto3" json:"rule,omitempty"` +} + +func (x *UpdateHTTPDNSCustomRuleRequest) Reset() { + *x = UpdateHTTPDNSCustomRuleRequest{} + mi := &file_service_httpdns_rule_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSCustomRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSCustomRuleRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSCustomRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_rule_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 UpdateHTTPDNSCustomRuleRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSCustomRuleRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_rule_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateHTTPDNSCustomRuleRequest) GetRule() *HTTPDNSCustomRule { + if x != nil { + return x.Rule + } + return nil +} + +type DeleteHTTPDNSCustomRuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RuleId int64 `protobuf:"varint,1,opt,name=ruleId,proto3" json:"ruleId,omitempty"` +} + +func (x *DeleteHTTPDNSCustomRuleRequest) Reset() { + *x = DeleteHTTPDNSCustomRuleRequest{} + mi := &file_service_httpdns_rule_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteHTTPDNSCustomRuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteHTTPDNSCustomRuleRequest) ProtoMessage() {} + +func (x *DeleteHTTPDNSCustomRuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_rule_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 DeleteHTTPDNSCustomRuleRequest.ProtoReflect.Descriptor instead. +func (*DeleteHTTPDNSCustomRuleRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_rule_proto_rawDescGZIP(), []int{3} +} + +func (x *DeleteHTTPDNSCustomRuleRequest) GetRuleId() int64 { + if x != nil { + return x.RuleId + } + return 0 +} + +type UpdateHTTPDNSCustomRuleStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RuleId int64 `protobuf:"varint,1,opt,name=ruleId,proto3" json:"ruleId,omitempty"` + IsOn bool `protobuf:"varint,2,opt,name=isOn,proto3" json:"isOn,omitempty"` +} + +func (x *UpdateHTTPDNSCustomRuleStatusRequest) Reset() { + *x = UpdateHTTPDNSCustomRuleStatusRequest{} + mi := &file_service_httpdns_rule_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateHTTPDNSCustomRuleStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateHTTPDNSCustomRuleStatusRequest) ProtoMessage() {} + +func (x *UpdateHTTPDNSCustomRuleStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_rule_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 UpdateHTTPDNSCustomRuleStatusRequest.ProtoReflect.Descriptor instead. +func (*UpdateHTTPDNSCustomRuleStatusRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_rule_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateHTTPDNSCustomRuleStatusRequest) GetRuleId() int64 { + if x != nil { + return x.RuleId + } + return 0 +} + +func (x *UpdateHTTPDNSCustomRuleStatusRequest) GetIsOn() bool { + if x != nil { + return x.IsOn + } + return false +} + +type ListHTTPDNSCustomRulesWithDomainIdRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DomainId int64 `protobuf:"varint,1,opt,name=domainId,proto3" json:"domainId,omitempty"` +} + +func (x *ListHTTPDNSCustomRulesWithDomainIdRequest) Reset() { + *x = ListHTTPDNSCustomRulesWithDomainIdRequest{} + mi := &file_service_httpdns_rule_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSCustomRulesWithDomainIdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSCustomRulesWithDomainIdRequest) ProtoMessage() {} + +func (x *ListHTTPDNSCustomRulesWithDomainIdRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_rule_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 ListHTTPDNSCustomRulesWithDomainIdRequest.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSCustomRulesWithDomainIdRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_rule_proto_rawDescGZIP(), []int{5} +} + +func (x *ListHTTPDNSCustomRulesWithDomainIdRequest) GetDomainId() int64 { + if x != nil { + return x.DomainId + } + return 0 +} + +type ListHTTPDNSCustomRulesWithDomainIdResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rules []*HTTPDNSCustomRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (x *ListHTTPDNSCustomRulesWithDomainIdResponse) Reset() { + *x = ListHTTPDNSCustomRulesWithDomainIdResponse{} + mi := &file_service_httpdns_rule_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSCustomRulesWithDomainIdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSCustomRulesWithDomainIdResponse) ProtoMessage() {} + +func (x *ListHTTPDNSCustomRulesWithDomainIdResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_rule_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 ListHTTPDNSCustomRulesWithDomainIdResponse.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSCustomRulesWithDomainIdResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_rule_proto_rawDescGZIP(), []int{6} +} + +func (x *ListHTTPDNSCustomRulesWithDomainIdResponse) GetRules() []*HTTPDNSCustomRule { + if x != nil { + return x.Rules + } + return nil +} + +var File_service_httpdns_rule_proto protoreflect.FileDescriptor + +var file_service_httpdns_rule_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, + 0x73, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, + 0x1a, 0x1f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, + 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x19, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x5f, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x1e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, + 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, + 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, + 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x22, 0x39, 0x0a, 0x1f, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x75, + 0x6c, 0x65, 0x49, 0x64, 0x22, 0x4b, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, + 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, + 0x65, 0x22, 0x38, 0x0a, 0x1e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x22, 0x52, 0x0a, 0x24, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x69, + 0x73, 0x4f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x22, + 0x47, 0x0a, 0x29, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, + 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0x59, 0x0a, 0x2a, 0x4c, 0x69, 0x73, 0x74, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, + 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, + 0x6c, 0x65, 0x73, 0x32, 0xf7, 0x03, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, + 0x75, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x17, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x62, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, + 0x0a, 0x17, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x62, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, + 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4d, 0x0a, + 0x17, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, + 0x62, 0x2e, 0x52, 0x50, 0x43, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x59, 0x0a, 0x1d, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x2e, + 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x50, 0x43, + 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x22, 0x6c, 0x69, 0x73, 0x74, + 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x2d, + 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, + 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x44, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x06, 0x5a, + 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_service_httpdns_rule_proto_rawDescOnce sync.Once + file_service_httpdns_rule_proto_rawDescData = file_service_httpdns_rule_proto_rawDesc +) + +func file_service_httpdns_rule_proto_rawDescGZIP() []byte { + file_service_httpdns_rule_proto_rawDescOnce.Do(func() { + file_service_httpdns_rule_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_httpdns_rule_proto_rawDescData) + }) + return file_service_httpdns_rule_proto_rawDescData +} + +var file_service_httpdns_rule_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_service_httpdns_rule_proto_goTypes = []any{ + (*CreateHTTPDNSCustomRuleRequest)(nil), // 0: pb.CreateHTTPDNSCustomRuleRequest + (*CreateHTTPDNSCustomRuleResponse)(nil), // 1: pb.CreateHTTPDNSCustomRuleResponse + (*UpdateHTTPDNSCustomRuleRequest)(nil), // 2: pb.UpdateHTTPDNSCustomRuleRequest + (*DeleteHTTPDNSCustomRuleRequest)(nil), // 3: pb.DeleteHTTPDNSCustomRuleRequest + (*UpdateHTTPDNSCustomRuleStatusRequest)(nil), // 4: pb.UpdateHTTPDNSCustomRuleStatusRequest + (*ListHTTPDNSCustomRulesWithDomainIdRequest)(nil), // 5: pb.ListHTTPDNSCustomRulesWithDomainIdRequest + (*ListHTTPDNSCustomRulesWithDomainIdResponse)(nil), // 6: pb.ListHTTPDNSCustomRulesWithDomainIdResponse + (*HTTPDNSCustomRule)(nil), // 7: pb.HTTPDNSCustomRule + (*RPCSuccess)(nil), // 8: pb.RPCSuccess +} +var file_service_httpdns_rule_proto_depIdxs = []int32{ + 7, // 0: pb.CreateHTTPDNSCustomRuleRequest.rule:type_name -> pb.HTTPDNSCustomRule + 7, // 1: pb.UpdateHTTPDNSCustomRuleRequest.rule:type_name -> pb.HTTPDNSCustomRule + 7, // 2: pb.ListHTTPDNSCustomRulesWithDomainIdResponse.rules:type_name -> pb.HTTPDNSCustomRule + 0, // 3: pb.HTTPDNSRuleService.createHTTPDNSCustomRule:input_type -> pb.CreateHTTPDNSCustomRuleRequest + 2, // 4: pb.HTTPDNSRuleService.updateHTTPDNSCustomRule:input_type -> pb.UpdateHTTPDNSCustomRuleRequest + 3, // 5: pb.HTTPDNSRuleService.deleteHTTPDNSCustomRule:input_type -> pb.DeleteHTTPDNSCustomRuleRequest + 4, // 6: pb.HTTPDNSRuleService.updateHTTPDNSCustomRuleStatus:input_type -> pb.UpdateHTTPDNSCustomRuleStatusRequest + 5, // 7: pb.HTTPDNSRuleService.listHTTPDNSCustomRulesWithDomainId:input_type -> pb.ListHTTPDNSCustomRulesWithDomainIdRequest + 1, // 8: pb.HTTPDNSRuleService.createHTTPDNSCustomRule:output_type -> pb.CreateHTTPDNSCustomRuleResponse + 8, // 9: pb.HTTPDNSRuleService.updateHTTPDNSCustomRule:output_type -> pb.RPCSuccess + 8, // 10: pb.HTTPDNSRuleService.deleteHTTPDNSCustomRule:output_type -> pb.RPCSuccess + 8, // 11: pb.HTTPDNSRuleService.updateHTTPDNSCustomRuleStatus:output_type -> pb.RPCSuccess + 6, // 12: pb.HTTPDNSRuleService.listHTTPDNSCustomRulesWithDomainId:output_type -> pb.ListHTTPDNSCustomRulesWithDomainIdResponse + 8, // [8:13] is the sub-list for method output_type + 3, // [3:8] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_service_httpdns_rule_proto_init() } +func file_service_httpdns_rule_proto_init() { + if File_service_httpdns_rule_proto != nil { + return + } + file_models_model_httpdns_rule_proto_init() + file_models_rpc_messages_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_service_httpdns_rule_proto_rawDesc, + NumEnums: 0, + NumMessages: 7, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_service_httpdns_rule_proto_goTypes, + DependencyIndexes: file_service_httpdns_rule_proto_depIdxs, + MessageInfos: file_service_httpdns_rule_proto_msgTypes, + }.Build() + File_service_httpdns_rule_proto = out.File + file_service_httpdns_rule_proto_rawDesc = nil + file_service_httpdns_rule_proto_goTypes = nil + file_service_httpdns_rule_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_rule_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_rule_grpc.pb.go new file mode 100644 index 0000000..3f8125f --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_rule_grpc.pb.go @@ -0,0 +1,271 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: service_httpdns_rule.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 ( + HTTPDNSRuleService_CreateHTTPDNSCustomRule_FullMethodName = "/pb.HTTPDNSRuleService/createHTTPDNSCustomRule" + HTTPDNSRuleService_UpdateHTTPDNSCustomRule_FullMethodName = "/pb.HTTPDNSRuleService/updateHTTPDNSCustomRule" + HTTPDNSRuleService_DeleteHTTPDNSCustomRule_FullMethodName = "/pb.HTTPDNSRuleService/deleteHTTPDNSCustomRule" + HTTPDNSRuleService_UpdateHTTPDNSCustomRuleStatus_FullMethodName = "/pb.HTTPDNSRuleService/updateHTTPDNSCustomRuleStatus" + HTTPDNSRuleService_ListHTTPDNSCustomRulesWithDomainId_FullMethodName = "/pb.HTTPDNSRuleService/listHTTPDNSCustomRulesWithDomainId" +) + +// HTTPDNSRuleServiceClient is the client API for HTTPDNSRuleService 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. +type HTTPDNSRuleServiceClient interface { + CreateHTTPDNSCustomRule(ctx context.Context, in *CreateHTTPDNSCustomRuleRequest, opts ...grpc.CallOption) (*CreateHTTPDNSCustomRuleResponse, error) + UpdateHTTPDNSCustomRule(ctx context.Context, in *UpdateHTTPDNSCustomRuleRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + DeleteHTTPDNSCustomRule(ctx context.Context, in *DeleteHTTPDNSCustomRuleRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + UpdateHTTPDNSCustomRuleStatus(ctx context.Context, in *UpdateHTTPDNSCustomRuleStatusRequest, opts ...grpc.CallOption) (*RPCSuccess, error) + ListHTTPDNSCustomRulesWithDomainId(ctx context.Context, in *ListHTTPDNSCustomRulesWithDomainIdRequest, opts ...grpc.CallOption) (*ListHTTPDNSCustomRulesWithDomainIdResponse, error) +} + +type hTTPDNSRuleServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHTTPDNSRuleServiceClient(cc grpc.ClientConnInterface) HTTPDNSRuleServiceClient { + return &hTTPDNSRuleServiceClient{cc} +} + +func (c *hTTPDNSRuleServiceClient) CreateHTTPDNSCustomRule(ctx context.Context, in *CreateHTTPDNSCustomRuleRequest, opts ...grpc.CallOption) (*CreateHTTPDNSCustomRuleResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateHTTPDNSCustomRuleResponse) + err := c.cc.Invoke(ctx, HTTPDNSRuleService_CreateHTTPDNSCustomRule_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSRuleServiceClient) UpdateHTTPDNSCustomRule(ctx context.Context, in *UpdateHTTPDNSCustomRuleRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSRuleService_UpdateHTTPDNSCustomRule_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSRuleServiceClient) DeleteHTTPDNSCustomRule(ctx context.Context, in *DeleteHTTPDNSCustomRuleRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSRuleService_DeleteHTTPDNSCustomRule_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSRuleServiceClient) UpdateHTTPDNSCustomRuleStatus(ctx context.Context, in *UpdateHTTPDNSCustomRuleStatusRequest, opts ...grpc.CallOption) (*RPCSuccess, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RPCSuccess) + err := c.cc.Invoke(ctx, HTTPDNSRuleService_UpdateHTTPDNSCustomRuleStatus_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSRuleServiceClient) ListHTTPDNSCustomRulesWithDomainId(ctx context.Context, in *ListHTTPDNSCustomRulesWithDomainIdRequest, opts ...grpc.CallOption) (*ListHTTPDNSCustomRulesWithDomainIdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListHTTPDNSCustomRulesWithDomainIdResponse) + err := c.cc.Invoke(ctx, HTTPDNSRuleService_ListHTTPDNSCustomRulesWithDomainId_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HTTPDNSRuleServiceServer is the server API for HTTPDNSRuleService service. +// All implementations should embed UnimplementedHTTPDNSRuleServiceServer +// for forward compatibility. +type HTTPDNSRuleServiceServer interface { + CreateHTTPDNSCustomRule(context.Context, *CreateHTTPDNSCustomRuleRequest) (*CreateHTTPDNSCustomRuleResponse, error) + UpdateHTTPDNSCustomRule(context.Context, *UpdateHTTPDNSCustomRuleRequest) (*RPCSuccess, error) + DeleteHTTPDNSCustomRule(context.Context, *DeleteHTTPDNSCustomRuleRequest) (*RPCSuccess, error) + UpdateHTTPDNSCustomRuleStatus(context.Context, *UpdateHTTPDNSCustomRuleStatusRequest) (*RPCSuccess, error) + ListHTTPDNSCustomRulesWithDomainId(context.Context, *ListHTTPDNSCustomRulesWithDomainIdRequest) (*ListHTTPDNSCustomRulesWithDomainIdResponse, error) +} + +// UnimplementedHTTPDNSRuleServiceServer 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 UnimplementedHTTPDNSRuleServiceServer struct{} + +func (UnimplementedHTTPDNSRuleServiceServer) CreateHTTPDNSCustomRule(context.Context, *CreateHTTPDNSCustomRuleRequest) (*CreateHTTPDNSCustomRuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHTTPDNSCustomRule not implemented") +} +func (UnimplementedHTTPDNSRuleServiceServer) UpdateHTTPDNSCustomRule(context.Context, *UpdateHTTPDNSCustomRuleRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSCustomRule not implemented") +} +func (UnimplementedHTTPDNSRuleServiceServer) DeleteHTTPDNSCustomRule(context.Context, *DeleteHTTPDNSCustomRuleRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteHTTPDNSCustomRule not implemented") +} +func (UnimplementedHTTPDNSRuleServiceServer) UpdateHTTPDNSCustomRuleStatus(context.Context, *UpdateHTTPDNSCustomRuleStatusRequest) (*RPCSuccess, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateHTTPDNSCustomRuleStatus not implemented") +} +func (UnimplementedHTTPDNSRuleServiceServer) ListHTTPDNSCustomRulesWithDomainId(context.Context, *ListHTTPDNSCustomRulesWithDomainIdRequest) (*ListHTTPDNSCustomRulesWithDomainIdResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListHTTPDNSCustomRulesWithDomainId not implemented") +} +func (UnimplementedHTTPDNSRuleServiceServer) testEmbeddedByValue() {} + +// UnsafeHTTPDNSRuleServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HTTPDNSRuleServiceServer will +// result in compilation errors. +type UnsafeHTTPDNSRuleServiceServer interface { + mustEmbedUnimplementedHTTPDNSRuleServiceServer() +} + +func RegisterHTTPDNSRuleServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSRuleServiceServer) { + // If the following call pancis, it indicates UnimplementedHTTPDNSRuleServiceServer 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(&HTTPDNSRuleService_ServiceDesc, srv) +} + +func _HTTPDNSRuleService_CreateHTTPDNSCustomRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateHTTPDNSCustomRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSRuleServiceServer).CreateHTTPDNSCustomRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSRuleService_CreateHTTPDNSCustomRule_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSRuleServiceServer).CreateHTTPDNSCustomRule(ctx, req.(*CreateHTTPDNSCustomRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSRuleService_UpdateHTTPDNSCustomRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSCustomRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSRuleServiceServer).UpdateHTTPDNSCustomRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSRuleService_UpdateHTTPDNSCustomRule_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSRuleServiceServer).UpdateHTTPDNSCustomRule(ctx, req.(*UpdateHTTPDNSCustomRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSRuleService_DeleteHTTPDNSCustomRule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteHTTPDNSCustomRuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSRuleServiceServer).DeleteHTTPDNSCustomRule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSRuleService_DeleteHTTPDNSCustomRule_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSRuleServiceServer).DeleteHTTPDNSCustomRule(ctx, req.(*DeleteHTTPDNSCustomRuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSRuleService_UpdateHTTPDNSCustomRuleStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateHTTPDNSCustomRuleStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSRuleServiceServer).UpdateHTTPDNSCustomRuleStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSRuleService_UpdateHTTPDNSCustomRuleStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSRuleServiceServer).UpdateHTTPDNSCustomRuleStatus(ctx, req.(*UpdateHTTPDNSCustomRuleStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSRuleService_ListHTTPDNSCustomRulesWithDomainId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListHTTPDNSCustomRulesWithDomainIdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSRuleServiceServer).ListHTTPDNSCustomRulesWithDomainId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSRuleService_ListHTTPDNSCustomRulesWithDomainId_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSRuleServiceServer).ListHTTPDNSCustomRulesWithDomainId(ctx, req.(*ListHTTPDNSCustomRulesWithDomainIdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HTTPDNSRuleService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSRuleService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HTTPDNSRuleService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.HTTPDNSRuleService", + HandlerType: (*HTTPDNSRuleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "createHTTPDNSCustomRule", + Handler: _HTTPDNSRuleService_CreateHTTPDNSCustomRule_Handler, + }, + { + MethodName: "updateHTTPDNSCustomRule", + Handler: _HTTPDNSRuleService_UpdateHTTPDNSCustomRule_Handler, + }, + { + MethodName: "deleteHTTPDNSCustomRule", + Handler: _HTTPDNSRuleService_DeleteHTTPDNSCustomRule_Handler, + }, + { + MethodName: "updateHTTPDNSCustomRuleStatus", + Handler: _HTTPDNSRuleService_UpdateHTTPDNSCustomRuleStatus_Handler, + }, + { + MethodName: "listHTTPDNSCustomRulesWithDomainId", + Handler: _HTTPDNSRuleService_ListHTTPDNSCustomRulesWithDomainId_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service_httpdns_rule.proto", +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_runtime_log.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_runtime_log.pb.go new file mode 100644 index 0000000..745b604 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_runtime_log.pb.go @@ -0,0 +1,359 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: service_httpdns_runtime_log.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 CreateHTTPDNSRuntimeLogsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Logs []*HTTPDNSRuntimeLog `protobuf:"bytes,1,rep,name=logs,proto3" json:"logs,omitempty"` +} + +func (x *CreateHTTPDNSRuntimeLogsRequest) Reset() { + *x = CreateHTTPDNSRuntimeLogsRequest{} + mi := &file_service_httpdns_runtime_log_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSRuntimeLogsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSRuntimeLogsRequest) ProtoMessage() {} + +func (x *CreateHTTPDNSRuntimeLogsRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_runtime_log_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 CreateHTTPDNSRuntimeLogsRequest.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSRuntimeLogsRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_runtime_log_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateHTTPDNSRuntimeLogsRequest) GetLogs() []*HTTPDNSRuntimeLog { + if x != nil { + return x.Logs + } + return nil +} + +type CreateHTTPDNSRuntimeLogsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *CreateHTTPDNSRuntimeLogsResponse) Reset() { + *x = CreateHTTPDNSRuntimeLogsResponse{} + mi := &file_service_httpdns_runtime_log_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateHTTPDNSRuntimeLogsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateHTTPDNSRuntimeLogsResponse) ProtoMessage() {} + +func (x *CreateHTTPDNSRuntimeLogsResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_runtime_log_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 CreateHTTPDNSRuntimeLogsResponse.ProtoReflect.Descriptor instead. +func (*CreateHTTPDNSRuntimeLogsResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_runtime_log_proto_rawDescGZIP(), []int{1} +} + +type ListHTTPDNSRuntimeLogsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Day string `protobuf:"bytes,1,opt,name=day,proto3" json:"day,omitempty"` + ClusterId int64 `protobuf:"varint,2,opt,name=clusterId,proto3" json:"clusterId,omitempty"` + NodeId int64 `protobuf:"varint,3,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + Level string `protobuf:"bytes,4,opt,name=level,proto3" json:"level,omitempty"` + Keyword string `protobuf:"bytes,5,opt,name=keyword,proto3" json:"keyword,omitempty"` + Offset int64 `protobuf:"varint,6,opt,name=offset,proto3" json:"offset,omitempty"` + Size int64 `protobuf:"varint,7,opt,name=size,proto3" json:"size,omitempty"` +} + +func (x *ListHTTPDNSRuntimeLogsRequest) Reset() { + *x = ListHTTPDNSRuntimeLogsRequest{} + mi := &file_service_httpdns_runtime_log_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSRuntimeLogsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSRuntimeLogsRequest) ProtoMessage() {} + +func (x *ListHTTPDNSRuntimeLogsRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_runtime_log_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 ListHTTPDNSRuntimeLogsRequest.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSRuntimeLogsRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_runtime_log_proto_rawDescGZIP(), []int{2} +} + +func (x *ListHTTPDNSRuntimeLogsRequest) GetDay() string { + if x != nil { + return x.Day + } + return "" +} + +func (x *ListHTTPDNSRuntimeLogsRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +func (x *ListHTTPDNSRuntimeLogsRequest) GetNodeId() int64 { + if x != nil { + return x.NodeId + } + return 0 +} + +func (x *ListHTTPDNSRuntimeLogsRequest) GetLevel() string { + if x != nil { + return x.Level + } + return "" +} + +func (x *ListHTTPDNSRuntimeLogsRequest) GetKeyword() string { + if x != nil { + return x.Keyword + } + return "" +} + +func (x *ListHTTPDNSRuntimeLogsRequest) GetOffset() int64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListHTTPDNSRuntimeLogsRequest) GetSize() int64 { + if x != nil { + return x.Size + } + return 0 +} + +type ListHTTPDNSRuntimeLogsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Logs []*HTTPDNSRuntimeLog `protobuf:"bytes,1,rep,name=logs,proto3" json:"logs,omitempty"` + Total int64 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` +} + +func (x *ListHTTPDNSRuntimeLogsResponse) Reset() { + *x = ListHTTPDNSRuntimeLogsResponse{} + mi := &file_service_httpdns_runtime_log_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListHTTPDNSRuntimeLogsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListHTTPDNSRuntimeLogsResponse) ProtoMessage() {} + +func (x *ListHTTPDNSRuntimeLogsResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_runtime_log_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 ListHTTPDNSRuntimeLogsResponse.ProtoReflect.Descriptor instead. +func (*ListHTTPDNSRuntimeLogsResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_runtime_log_proto_rawDescGZIP(), []int{3} +} + +func (x *ListHTTPDNSRuntimeLogsResponse) GetLogs() []*HTTPDNSRuntimeLog { + if x != nil { + return x.Logs + } + return nil +} + +func (x *ListHTTPDNSRuntimeLogsResponse) GetTotal() int64 { + if x != nil { + return x.Total + } + return 0 +} + +var File_service_httpdns_runtime_log_proto protoreflect.FileDescriptor + +var file_service_httpdns_runtime_log_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, + 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x26, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, 0x73, 0x5f, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x4c, 0x0a, 0x1f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x29, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x22, 0x0a, + 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, + 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x64, 0x61, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, + 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x61, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x48, + 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x04, 0x6c, 0x6f, 0x67, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x54, 0x54, + 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x52, 0x04, + 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x32, 0xe2, 0x01, 0x0a, 0x18, 0x48, + 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x65, 0x0a, 0x18, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, + 0x6f, 0x67, 0x73, 0x12, 0x23, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, + 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, + 0x0a, 0x16, 0x6c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x62, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_service_httpdns_runtime_log_proto_rawDescOnce sync.Once + file_service_httpdns_runtime_log_proto_rawDescData = file_service_httpdns_runtime_log_proto_rawDesc +) + +func file_service_httpdns_runtime_log_proto_rawDescGZIP() []byte { + file_service_httpdns_runtime_log_proto_rawDescOnce.Do(func() { + file_service_httpdns_runtime_log_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_httpdns_runtime_log_proto_rawDescData) + }) + return file_service_httpdns_runtime_log_proto_rawDescData +} + +var file_service_httpdns_runtime_log_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_service_httpdns_runtime_log_proto_goTypes = []any{ + (*CreateHTTPDNSRuntimeLogsRequest)(nil), // 0: pb.CreateHTTPDNSRuntimeLogsRequest + (*CreateHTTPDNSRuntimeLogsResponse)(nil), // 1: pb.CreateHTTPDNSRuntimeLogsResponse + (*ListHTTPDNSRuntimeLogsRequest)(nil), // 2: pb.ListHTTPDNSRuntimeLogsRequest + (*ListHTTPDNSRuntimeLogsResponse)(nil), // 3: pb.ListHTTPDNSRuntimeLogsResponse + (*HTTPDNSRuntimeLog)(nil), // 4: pb.HTTPDNSRuntimeLog +} +var file_service_httpdns_runtime_log_proto_depIdxs = []int32{ + 4, // 0: pb.CreateHTTPDNSRuntimeLogsRequest.logs:type_name -> pb.HTTPDNSRuntimeLog + 4, // 1: pb.ListHTTPDNSRuntimeLogsResponse.logs:type_name -> pb.HTTPDNSRuntimeLog + 0, // 2: pb.HTTPDNSRuntimeLogService.createHTTPDNSRuntimeLogs:input_type -> pb.CreateHTTPDNSRuntimeLogsRequest + 2, // 3: pb.HTTPDNSRuntimeLogService.listHTTPDNSRuntimeLogs:input_type -> pb.ListHTTPDNSRuntimeLogsRequest + 1, // 4: pb.HTTPDNSRuntimeLogService.createHTTPDNSRuntimeLogs:output_type -> pb.CreateHTTPDNSRuntimeLogsResponse + 3, // 5: pb.HTTPDNSRuntimeLogService.listHTTPDNSRuntimeLogs:output_type -> pb.ListHTTPDNSRuntimeLogsResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_service_httpdns_runtime_log_proto_init() } +func file_service_httpdns_runtime_log_proto_init() { + if File_service_httpdns_runtime_log_proto != nil { + return + } + file_models_model_httpdns_runtime_log_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_service_httpdns_runtime_log_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_service_httpdns_runtime_log_proto_goTypes, + DependencyIndexes: file_service_httpdns_runtime_log_proto_depIdxs, + MessageInfos: file_service_httpdns_runtime_log_proto_msgTypes, + }.Build() + File_service_httpdns_runtime_log_proto = out.File + file_service_httpdns_runtime_log_proto_rawDesc = nil + file_service_httpdns_runtime_log_proto_goTypes = nil + file_service_httpdns_runtime_log_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_runtime_log_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_runtime_log_grpc.pb.go new file mode 100644 index 0000000..ad2e296 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_runtime_log_grpc.pb.go @@ -0,0 +1,157 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: service_httpdns_runtime_log.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 ( + HTTPDNSRuntimeLogService_CreateHTTPDNSRuntimeLogs_FullMethodName = "/pb.HTTPDNSRuntimeLogService/createHTTPDNSRuntimeLogs" + HTTPDNSRuntimeLogService_ListHTTPDNSRuntimeLogs_FullMethodName = "/pb.HTTPDNSRuntimeLogService/listHTTPDNSRuntimeLogs" +) + +// HTTPDNSRuntimeLogServiceClient is the client API for HTTPDNSRuntimeLogService 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. +type HTTPDNSRuntimeLogServiceClient interface { + CreateHTTPDNSRuntimeLogs(ctx context.Context, in *CreateHTTPDNSRuntimeLogsRequest, opts ...grpc.CallOption) (*CreateHTTPDNSRuntimeLogsResponse, error) + ListHTTPDNSRuntimeLogs(ctx context.Context, in *ListHTTPDNSRuntimeLogsRequest, opts ...grpc.CallOption) (*ListHTTPDNSRuntimeLogsResponse, error) +} + +type hTTPDNSRuntimeLogServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHTTPDNSRuntimeLogServiceClient(cc grpc.ClientConnInterface) HTTPDNSRuntimeLogServiceClient { + return &hTTPDNSRuntimeLogServiceClient{cc} +} + +func (c *hTTPDNSRuntimeLogServiceClient) CreateHTTPDNSRuntimeLogs(ctx context.Context, in *CreateHTTPDNSRuntimeLogsRequest, opts ...grpc.CallOption) (*CreateHTTPDNSRuntimeLogsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateHTTPDNSRuntimeLogsResponse) + err := c.cc.Invoke(ctx, HTTPDNSRuntimeLogService_CreateHTTPDNSRuntimeLogs_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *hTTPDNSRuntimeLogServiceClient) ListHTTPDNSRuntimeLogs(ctx context.Context, in *ListHTTPDNSRuntimeLogsRequest, opts ...grpc.CallOption) (*ListHTTPDNSRuntimeLogsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListHTTPDNSRuntimeLogsResponse) + err := c.cc.Invoke(ctx, HTTPDNSRuntimeLogService_ListHTTPDNSRuntimeLogs_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HTTPDNSRuntimeLogServiceServer is the server API for HTTPDNSRuntimeLogService service. +// All implementations should embed UnimplementedHTTPDNSRuntimeLogServiceServer +// for forward compatibility. +type HTTPDNSRuntimeLogServiceServer interface { + CreateHTTPDNSRuntimeLogs(context.Context, *CreateHTTPDNSRuntimeLogsRequest) (*CreateHTTPDNSRuntimeLogsResponse, error) + ListHTTPDNSRuntimeLogs(context.Context, *ListHTTPDNSRuntimeLogsRequest) (*ListHTTPDNSRuntimeLogsResponse, error) +} + +// UnimplementedHTTPDNSRuntimeLogServiceServer 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 UnimplementedHTTPDNSRuntimeLogServiceServer struct{} + +func (UnimplementedHTTPDNSRuntimeLogServiceServer) CreateHTTPDNSRuntimeLogs(context.Context, *CreateHTTPDNSRuntimeLogsRequest) (*CreateHTTPDNSRuntimeLogsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHTTPDNSRuntimeLogs not implemented") +} +func (UnimplementedHTTPDNSRuntimeLogServiceServer) ListHTTPDNSRuntimeLogs(context.Context, *ListHTTPDNSRuntimeLogsRequest) (*ListHTTPDNSRuntimeLogsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListHTTPDNSRuntimeLogs not implemented") +} +func (UnimplementedHTTPDNSRuntimeLogServiceServer) testEmbeddedByValue() {} + +// UnsafeHTTPDNSRuntimeLogServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HTTPDNSRuntimeLogServiceServer will +// result in compilation errors. +type UnsafeHTTPDNSRuntimeLogServiceServer interface { + mustEmbedUnimplementedHTTPDNSRuntimeLogServiceServer() +} + +func RegisterHTTPDNSRuntimeLogServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSRuntimeLogServiceServer) { + // If the following call pancis, it indicates UnimplementedHTTPDNSRuntimeLogServiceServer 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(&HTTPDNSRuntimeLogService_ServiceDesc, srv) +} + +func _HTTPDNSRuntimeLogService_CreateHTTPDNSRuntimeLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateHTTPDNSRuntimeLogsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSRuntimeLogServiceServer).CreateHTTPDNSRuntimeLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSRuntimeLogService_CreateHTTPDNSRuntimeLogs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSRuntimeLogServiceServer).CreateHTTPDNSRuntimeLogs(ctx, req.(*CreateHTTPDNSRuntimeLogsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _HTTPDNSRuntimeLogService_ListHTTPDNSRuntimeLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListHTTPDNSRuntimeLogsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSRuntimeLogServiceServer).ListHTTPDNSRuntimeLogs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSRuntimeLogService_ListHTTPDNSRuntimeLogs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSRuntimeLogServiceServer).ListHTTPDNSRuntimeLogs(ctx, req.(*ListHTTPDNSRuntimeLogsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HTTPDNSRuntimeLogService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSRuntimeLogService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HTTPDNSRuntimeLogService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.HTTPDNSRuntimeLogService", + HandlerType: (*HTTPDNSRuntimeLogServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "createHTTPDNSRuntimeLogs", + Handler: _HTTPDNSRuntimeLogService_CreateHTTPDNSRuntimeLogs_Handler, + }, + { + MethodName: "listHTTPDNSRuntimeLogs", + Handler: _HTTPDNSRuntimeLogService_ListHTTPDNSRuntimeLogs_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service_httpdns_runtime_log.proto", +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_sandbox.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_sandbox.pb.go new file mode 100644 index 0000000..6b4be37 --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_sandbox.pb.go @@ -0,0 +1,460 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v3.21.12 +// source: service_httpdns_sandbox.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 TestHTTPDNSResolveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"` + AppId string `protobuf:"bytes,2,opt,name=appId,proto3" json:"appId,omitempty"` + Domain string `protobuf:"bytes,3,opt,name=domain,proto3" json:"domain,omitempty"` + Qtype string `protobuf:"bytes,4,opt,name=qtype,proto3" json:"qtype,omitempty"` + ClientIP string `protobuf:"bytes,5,opt,name=clientIP,proto3" json:"clientIP,omitempty"` + Sid string `protobuf:"bytes,6,opt,name=sid,proto3" json:"sid,omitempty"` + SdkVersion string `protobuf:"bytes,7,opt,name=sdkVersion,proto3" json:"sdkVersion,omitempty"` + Os string `protobuf:"bytes,8,opt,name=os,proto3" json:"os,omitempty"` +} + +func (x *TestHTTPDNSResolveRequest) Reset() { + *x = TestHTTPDNSResolveRequest{} + mi := &file_service_httpdns_sandbox_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TestHTTPDNSResolveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestHTTPDNSResolveRequest) ProtoMessage() {} + +func (x *TestHTTPDNSResolveRequest) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_sandbox_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 TestHTTPDNSResolveRequest.ProtoReflect.Descriptor instead. +func (*TestHTTPDNSResolveRequest) Descriptor() ([]byte, []int) { + return file_service_httpdns_sandbox_proto_rawDescGZIP(), []int{0} +} + +func (x *TestHTTPDNSResolveRequest) GetClusterId() int64 { + if x != nil { + return x.ClusterId + } + return 0 +} + +func (x *TestHTTPDNSResolveRequest) GetAppId() string { + if x != nil { + return x.AppId + } + return "" +} + +func (x *TestHTTPDNSResolveRequest) GetDomain() string { + if x != nil { + return x.Domain + } + return "" +} + +func (x *TestHTTPDNSResolveRequest) GetQtype() string { + if x != nil { + return x.Qtype + } + return "" +} + +func (x *TestHTTPDNSResolveRequest) GetClientIP() string { + if x != nil { + return x.ClientIP + } + return "" +} + +func (x *TestHTTPDNSResolveRequest) GetSid() string { + if x != nil { + return x.Sid + } + return "" +} + +func (x *TestHTTPDNSResolveRequest) GetSdkVersion() string { + if x != nil { + return x.SdkVersion + } + return "" +} + +func (x *TestHTTPDNSResolveRequest) GetOs() string { + if x != nil { + return x.Os + } + return "" +} + +type HTTPDNSResolveRecord struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Ip string `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"` + Ttl int32 `protobuf:"varint,3,opt,name=ttl,proto3" json:"ttl,omitempty"` + Weight int32 `protobuf:"varint,4,opt,name=weight,proto3" json:"weight,omitempty"` + Line string `protobuf:"bytes,5,opt,name=line,proto3" json:"line,omitempty"` + Region string `protobuf:"bytes,6,opt,name=region,proto3" json:"region,omitempty"` +} + +func (x *HTTPDNSResolveRecord) Reset() { + *x = HTTPDNSResolveRecord{} + mi := &file_service_httpdns_sandbox_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HTTPDNSResolveRecord) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HTTPDNSResolveRecord) ProtoMessage() {} + +func (x *HTTPDNSResolveRecord) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_sandbox_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 HTTPDNSResolveRecord.ProtoReflect.Descriptor instead. +func (*HTTPDNSResolveRecord) Descriptor() ([]byte, []int) { + return file_service_httpdns_sandbox_proto_rawDescGZIP(), []int{1} +} + +func (x *HTTPDNSResolveRecord) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *HTTPDNSResolveRecord) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *HTTPDNSResolveRecord) GetTtl() int32 { + if x != nil { + return x.Ttl + } + return 0 +} + +func (x *HTTPDNSResolveRecord) GetWeight() int32 { + if x != nil { + return x.Weight + } + return 0 +} + +func (x *HTTPDNSResolveRecord) GetLine() string { + if x != nil { + return x.Line + } + return "" +} + +func (x *HTTPDNSResolveRecord) GetRegion() string { + if x != nil { + return x.Region + } + return "" +} + +type TestHTTPDNSResolveResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + RequestId string `protobuf:"bytes,3,opt,name=requestId,proto3" json:"requestId,omitempty"` + Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"` + Qtype string `protobuf:"bytes,5,opt,name=qtype,proto3" json:"qtype,omitempty"` + Ttl int32 `protobuf:"varint,6,opt,name=ttl,proto3" json:"ttl,omitempty"` + Records []*HTTPDNSResolveRecord `protobuf:"bytes,7,rep,name=records,proto3" json:"records,omitempty"` + ClientIP string `protobuf:"bytes,8,opt,name=clientIP,proto3" json:"clientIP,omitempty"` + ClientRegion string `protobuf:"bytes,9,opt,name=clientRegion,proto3" json:"clientRegion,omitempty"` + ClientCarrier string `protobuf:"bytes,10,opt,name=clientCarrier,proto3" json:"clientCarrier,omitempty"` + ClientCountry string `protobuf:"bytes,11,opt,name=clientCountry,proto3" json:"clientCountry,omitempty"` + Summary string `protobuf:"bytes,12,opt,name=summary,proto3" json:"summary,omitempty"` +} + +func (x *TestHTTPDNSResolveResponse) Reset() { + *x = TestHTTPDNSResolveResponse{} + mi := &file_service_httpdns_sandbox_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TestHTTPDNSResolveResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestHTTPDNSResolveResponse) ProtoMessage() {} + +func (x *TestHTTPDNSResolveResponse) ProtoReflect() protoreflect.Message { + mi := &file_service_httpdns_sandbox_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 TestHTTPDNSResolveResponse.ProtoReflect.Descriptor instead. +func (*TestHTTPDNSResolveResponse) Descriptor() ([]byte, []int) { + return file_service_httpdns_sandbox_proto_rawDescGZIP(), []int{2} +} + +func (x *TestHTTPDNSResolveResponse) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetDomain() string { + if x != nil { + return x.Domain + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetQtype() string { + if x != nil { + return x.Qtype + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetTtl() int32 { + if x != nil { + return x.Ttl + } + return 0 +} + +func (x *TestHTTPDNSResolveResponse) GetRecords() []*HTTPDNSResolveRecord { + if x != nil { + return x.Records + } + return nil +} + +func (x *TestHTTPDNSResolveResponse) GetClientIP() string { + if x != nil { + return x.ClientIP + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetClientRegion() string { + if x != nil { + return x.ClientRegion + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetClientCarrier() string { + if x != nil { + return x.ClientCarrier + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetClientCountry() string { + if x != nil { + return x.ClientCountry + } + return "" +} + +func (x *TestHTTPDNSResolveResponse) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +var File_service_httpdns_sandbox_proto protoreflect.FileDescriptor + +var file_service_httpdns_sandbox_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x6e, + 0x73, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x02, 0x70, 0x62, 0x1a, 0x19, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdb, + 0x01, 0x0a, 0x19, 0x54, 0x65, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x65, + 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, + 0x70, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, + 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, + 0x6f, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x22, 0x90, 0x01, 0x0a, + 0x14, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, + 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x22, + 0x82, 0x03, 0x0a, 0x1a, 0x54, 0x65, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x71, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x62, + 0x2e, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x50, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x24, + 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x72, + 0x72, 0x69, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x32, 0x6c, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x53, + 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x53, 0x0a, + 0x12, 0x74, 0x65, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x12, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x48, 0x54, 0x54, + 0x50, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x48, 0x54, 0x54, 0x50, + 0x44, 0x4e, 0x53, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_service_httpdns_sandbox_proto_rawDescOnce sync.Once + file_service_httpdns_sandbox_proto_rawDescData = file_service_httpdns_sandbox_proto_rawDesc +) + +func file_service_httpdns_sandbox_proto_rawDescGZIP() []byte { + file_service_httpdns_sandbox_proto_rawDescOnce.Do(func() { + file_service_httpdns_sandbox_proto_rawDescData = protoimpl.X.CompressGZIP(file_service_httpdns_sandbox_proto_rawDescData) + }) + return file_service_httpdns_sandbox_proto_rawDescData +} + +var file_service_httpdns_sandbox_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_service_httpdns_sandbox_proto_goTypes = []any{ + (*TestHTTPDNSResolveRequest)(nil), // 0: pb.TestHTTPDNSResolveRequest + (*HTTPDNSResolveRecord)(nil), // 1: pb.HTTPDNSResolveRecord + (*TestHTTPDNSResolveResponse)(nil), // 2: pb.TestHTTPDNSResolveResponse +} +var file_service_httpdns_sandbox_proto_depIdxs = []int32{ + 1, // 0: pb.TestHTTPDNSResolveResponse.records:type_name -> pb.HTTPDNSResolveRecord + 0, // 1: pb.HTTPDNSSandboxService.testHTTPDNSResolve:input_type -> pb.TestHTTPDNSResolveRequest + 2, // 2: pb.HTTPDNSSandboxService.testHTTPDNSResolve:output_type -> pb.TestHTTPDNSResolveResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_service_httpdns_sandbox_proto_init() } +func file_service_httpdns_sandbox_proto_init() { + if File_service_httpdns_sandbox_proto != nil { + return + } + file_models_rpc_messages_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_service_httpdns_sandbox_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_service_httpdns_sandbox_proto_goTypes, + DependencyIndexes: file_service_httpdns_sandbox_proto_depIdxs, + MessageInfos: file_service_httpdns_sandbox_proto_msgTypes, + }.Build() + File_service_httpdns_sandbox_proto = out.File + file_service_httpdns_sandbox_proto_rawDesc = nil + file_service_httpdns_sandbox_proto_goTypes = nil + file_service_httpdns_sandbox_proto_depIdxs = nil +} diff --git a/EdgeCommon/pkg/rpc/pb/service_httpdns_sandbox_grpc.pb.go b/EdgeCommon/pkg/rpc/pb/service_httpdns_sandbox_grpc.pb.go new file mode 100644 index 0000000..e7b9daa --- /dev/null +++ b/EdgeCommon/pkg/rpc/pb/service_httpdns_sandbox_grpc.pb.go @@ -0,0 +1,119 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v3.21.12 +// source: service_httpdns_sandbox.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 ( + HTTPDNSSandboxService_TestHTTPDNSResolve_FullMethodName = "/pb.HTTPDNSSandboxService/testHTTPDNSResolve" +) + +// HTTPDNSSandboxServiceClient is the client API for HTTPDNSSandboxService 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. +type HTTPDNSSandboxServiceClient interface { + TestHTTPDNSResolve(ctx context.Context, in *TestHTTPDNSResolveRequest, opts ...grpc.CallOption) (*TestHTTPDNSResolveResponse, error) +} + +type hTTPDNSSandboxServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHTTPDNSSandboxServiceClient(cc grpc.ClientConnInterface) HTTPDNSSandboxServiceClient { + return &hTTPDNSSandboxServiceClient{cc} +} + +func (c *hTTPDNSSandboxServiceClient) TestHTTPDNSResolve(ctx context.Context, in *TestHTTPDNSResolveRequest, opts ...grpc.CallOption) (*TestHTTPDNSResolveResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(TestHTTPDNSResolveResponse) + err := c.cc.Invoke(ctx, HTTPDNSSandboxService_TestHTTPDNSResolve_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// HTTPDNSSandboxServiceServer is the server API for HTTPDNSSandboxService service. +// All implementations should embed UnimplementedHTTPDNSSandboxServiceServer +// for forward compatibility. +type HTTPDNSSandboxServiceServer interface { + TestHTTPDNSResolve(context.Context, *TestHTTPDNSResolveRequest) (*TestHTTPDNSResolveResponse, error) +} + +// UnimplementedHTTPDNSSandboxServiceServer 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 UnimplementedHTTPDNSSandboxServiceServer struct{} + +func (UnimplementedHTTPDNSSandboxServiceServer) TestHTTPDNSResolve(context.Context, *TestHTTPDNSResolveRequest) (*TestHTTPDNSResolveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TestHTTPDNSResolve not implemented") +} +func (UnimplementedHTTPDNSSandboxServiceServer) testEmbeddedByValue() {} + +// UnsafeHTTPDNSSandboxServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to HTTPDNSSandboxServiceServer will +// result in compilation errors. +type UnsafeHTTPDNSSandboxServiceServer interface { + mustEmbedUnimplementedHTTPDNSSandboxServiceServer() +} + +func RegisterHTTPDNSSandboxServiceServer(s grpc.ServiceRegistrar, srv HTTPDNSSandboxServiceServer) { + // If the following call pancis, it indicates UnimplementedHTTPDNSSandboxServiceServer 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(&HTTPDNSSandboxService_ServiceDesc, srv) +} + +func _HTTPDNSSandboxService_TestHTTPDNSResolve_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TestHTTPDNSResolveRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HTTPDNSSandboxServiceServer).TestHTTPDNSResolve(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HTTPDNSSandboxService_TestHTTPDNSResolve_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HTTPDNSSandboxServiceServer).TestHTTPDNSResolve(ctx, req.(*TestHTTPDNSResolveRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// HTTPDNSSandboxService_ServiceDesc is the grpc.ServiceDesc for HTTPDNSSandboxService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var HTTPDNSSandboxService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pb.HTTPDNSSandboxService", + HandlerType: (*HTTPDNSSandboxServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "testHTTPDNSResolve", + Handler: _HTTPDNSSandboxService_TestHTTPDNSResolve_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service_httpdns_sandbox.proto", +} diff --git a/EdgeCommon/pkg/rpc/protos/models/model_httpdns_access_log.proto b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_access_log.proto new file mode 100644 index 0000000..fe23460 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_access_log.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +message HTTPDNSAccessLog { + int64 id = 1; + string requestId = 2; + int64 clusterId = 3; + int64 nodeId = 4; + string appId = 5; + string appName = 6; + string domain = 7; + string qtype = 8; + string clientIP = 9; + string clientRegion = 10; + string carrier = 11; + string sdkVersion = 12; + string os = 13; + string resultIPs = 14; + string status = 15; + string errorCode = 16; + int32 costMs = 17; + int64 createdAt = 18; + string day = 19; + string summary = 20; + string nodeName = 21; + string clusterName = 22; +} diff --git a/EdgeCommon/pkg/rpc/protos/models/model_httpdns_app.proto b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_app.proto new file mode 100644 index 0000000..3c37338 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_app.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +message HTTPDNSApp { + int64 id = 1; + string name = 2; + string appId = 3; + bool isOn = 4; + int64 primaryClusterId = 5; + int64 backupClusterId = 6; + string sniMode = 7; + bool signEnabled = 8; + string signSecret = 9; + int64 signUpdatedAt = 10; + int64 createdAt = 11; + int64 updatedAt = 12; + int64 userId = 13; +} diff --git a/EdgeCommon/pkg/rpc/protos/models/model_httpdns_cluster.proto b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_cluster.proto new file mode 100644 index 0000000..f9e25aa --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_cluster.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +message HTTPDNSCluster { + int64 id = 1; + bool isOn = 2; + bool isDefault = 3; + string name = 4; + string serviceDomain = 5; + int32 defaultTTL = 6; + int32 fallbackTimeoutMs = 7; + string installDir = 8; + bytes tlsPolicyJSON = 9; + int64 createdAt = 10; + int64 updatedAt = 11; +} diff --git a/EdgeCommon/pkg/rpc/protos/models/model_httpdns_domain.proto b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_domain.proto new file mode 100644 index 0000000..5b7f3f0 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_domain.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +message HTTPDNSDomain { + int64 id = 1; + int64 appId = 2; + string domain = 3; + bool isOn = 4; + int64 createdAt = 5; + int64 updatedAt = 6; + int64 ruleCount = 7; +} diff --git a/EdgeCommon/pkg/rpc/protos/models/model_httpdns_node.proto b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_node.proto new file mode 100644 index 0000000..1cafade --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_node.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +message HTTPDNSNode { + int64 id = 1; + int64 clusterId = 2; + string name = 3; + bool isOn = 4; + bool isUp = 5; + bool isInstalled = 6; + bool isActive = 7; + string uniqueId = 8; + string secret = 9; + string installDir = 10; + bytes statusJSON = 11; + bytes installStatusJSON = 12; + int64 createdAt = 13; + int64 updatedAt = 14; +} diff --git a/EdgeCommon/pkg/rpc/protos/models/model_httpdns_rule.proto b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_rule.proto new file mode 100644 index 0000000..7141520 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_rule.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +message HTTPDNSRuleRecord { + int64 id = 1; + int64 ruleId = 2; + string recordType = 3; + string recordValue = 4; + int32 weight = 5; + int32 sort = 6; +} + +message HTTPDNSCustomRule { + int64 id = 1; + int64 appId = 2; + int64 domainId = 3; + string ruleName = 4; + string lineScope = 5; + string lineCarrier = 6; + string lineRegion = 7; + string lineProvince = 8; + string lineContinent = 9; + string lineCountry = 10; + int32 ttl = 11; + bool isOn = 12; + int32 priority = 13; + int64 updatedAt = 14; + repeated HTTPDNSRuleRecord records = 15; +} diff --git a/EdgeCommon/pkg/rpc/protos/models/model_httpdns_runtime_log.proto b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_runtime_log.proto new file mode 100644 index 0000000..73e7069 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/models/model_httpdns_runtime_log.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +message HTTPDNSRuntimeLog { + int64 id = 1; + int64 clusterId = 2; + int64 nodeId = 3; + string level = 4; + string type = 5; + string module = 6; + string description = 7; + int64 count = 8; + string requestId = 9; + int64 createdAt = 10; + string day = 11; + string clusterName = 12; + string nodeName = 13; +} diff --git a/EdgeCommon/pkg/rpc/protos/service_httpdns_access_log.proto b/EdgeCommon/pkg/rpc/protos/service_httpdns_access_log.proto new file mode 100644 index 0000000..766eb64 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/service_httpdns_access_log.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +import "models/model_httpdns_access_log.proto"; + +service HTTPDNSAccessLogService { + rpc createHTTPDNSAccessLogs (CreateHTTPDNSAccessLogsRequest) returns (CreateHTTPDNSAccessLogsResponse); + rpc listHTTPDNSAccessLogs (ListHTTPDNSAccessLogsRequest) returns (ListHTTPDNSAccessLogsResponse); +} + +message CreateHTTPDNSAccessLogsRequest { + repeated HTTPDNSAccessLog logs = 1; +} + +message CreateHTTPDNSAccessLogsResponse { +} + +message ListHTTPDNSAccessLogsRequest { + string day = 1; + int64 clusterId = 2; + int64 nodeId = 3; + string appId = 4; + string domain = 5; + string status = 6; + string keyword = 7; + int64 offset = 8; + int64 size = 9; +} + +message ListHTTPDNSAccessLogsResponse { + repeated HTTPDNSAccessLog logs = 1; + int64 total = 2; +} diff --git a/EdgeCommon/pkg/rpc/protos/service_httpdns_app.proto b/EdgeCommon/pkg/rpc/protos/service_httpdns_app.proto new file mode 100644 index 0000000..155bccd --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/service_httpdns_app.proto @@ -0,0 +1,84 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +import "models/model_httpdns_app.proto"; +import "models/rpc_messages.proto"; + +service HTTPDNSAppService { + rpc createHTTPDNSApp (CreateHTTPDNSAppRequest) returns (CreateHTTPDNSAppResponse); + rpc updateHTTPDNSApp (UpdateHTTPDNSAppRequest) returns (RPCSuccess); + rpc deleteHTTPDNSApp (DeleteHTTPDNSAppRequest) returns (RPCSuccess); + rpc findHTTPDNSApp (FindHTTPDNSAppRequest) returns (FindHTTPDNSAppResponse); + rpc listHTTPDNSApps (ListHTTPDNSAppsRequest) returns (ListHTTPDNSAppsResponse); + rpc findAllHTTPDNSApps (FindAllHTTPDNSAppsRequest) returns (FindAllHTTPDNSAppsResponse); + rpc updateHTTPDNSAppSignEnabled (UpdateHTTPDNSAppSignEnabledRequest) returns (RPCSuccess); + rpc resetHTTPDNSAppSignSecret (ResetHTTPDNSAppSignSecretRequest) returns (ResetHTTPDNSAppSignSecretResponse); +} + +message CreateHTTPDNSAppRequest { + string name = 1; + string appId = 2; + int64 primaryClusterId = 3; + int64 backupClusterId = 4; + bool isOn = 5; + bool signEnabled = 6; + int64 userId = 7; +} + +message CreateHTTPDNSAppResponse { + int64 appDbId = 1; +} + +message UpdateHTTPDNSAppRequest { + int64 appDbId = 1; + string name = 2; + int64 primaryClusterId = 3; + int64 backupClusterId = 4; + bool isOn = 5; + int64 userId = 6; +} + +message DeleteHTTPDNSAppRequest { + int64 appDbId = 1; +} + +message FindHTTPDNSAppRequest { + int64 appDbId = 1; +} + +message FindHTTPDNSAppResponse { + HTTPDNSApp app = 1; +} + +message ListHTTPDNSAppsRequest { + int64 offset = 1; + int64 size = 2; + string keyword = 3; +} + +message ListHTTPDNSAppsResponse { + repeated HTTPDNSApp apps = 1; +} + +message FindAllHTTPDNSAppsRequest { +} + +message FindAllHTTPDNSAppsResponse { + repeated HTTPDNSApp apps = 1; +} + +message UpdateHTTPDNSAppSignEnabledRequest { + int64 appDbId = 1; + bool signEnabled = 2; +} + +message ResetHTTPDNSAppSignSecretRequest { + int64 appDbId = 1; +} + +message ResetHTTPDNSAppSignSecretResponse { + string signSecret = 1; + int64 updatedAt = 2; +} diff --git a/EdgeCommon/pkg/rpc/protos/service_httpdns_cluster.proto b/EdgeCommon/pkg/rpc/protos/service_httpdns_cluster.proto new file mode 100644 index 0000000..f9ea0a6 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/service_httpdns_cluster.proto @@ -0,0 +1,87 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +import "models/model_httpdns_cluster.proto"; +import "models/model_httpdns_node.proto"; +import "models/rpc_messages.proto"; + +service HTTPDNSClusterService { + rpc createHTTPDNSCluster (CreateHTTPDNSClusterRequest) returns (CreateHTTPDNSClusterResponse); + rpc updateHTTPDNSCluster (UpdateHTTPDNSClusterRequest) returns (RPCSuccess); + rpc deleteHTTPDNSCluster (DeleteHTTPDNSClusterRequest) returns (RPCSuccess); + rpc findHTTPDNSCluster (FindHTTPDNSClusterRequest) returns (FindHTTPDNSClusterResponse); + rpc listHTTPDNSClusters (ListHTTPDNSClustersRequest) returns (ListHTTPDNSClustersResponse); + rpc findAllHTTPDNSClusters (FindAllHTTPDNSClustersRequest) returns (FindAllHTTPDNSClustersResponse); + rpc updateHTTPDNSClusterDefault (UpdateHTTPDNSClusterDefaultRequest) returns (RPCSuccess); + rpc listHTTPDNSNodesWithClusterId (ListHTTPDNSNodesWithClusterIdRequest) returns (ListHTTPDNSNodesWithClusterIdResponse); +} + +message CreateHTTPDNSClusterRequest { + string name = 1; + string serviceDomain = 2; + int32 defaultTTL = 3; + int32 fallbackTimeoutMs = 4; + string installDir = 5; + bytes tlsPolicyJSON = 6; + bool isOn = 7; + bool isDefault = 8; +} + +message CreateHTTPDNSClusterResponse { + int64 clusterId = 1; +} + +message UpdateHTTPDNSClusterRequest { + int64 clusterId = 1; + string name = 2; + string serviceDomain = 3; + int32 defaultTTL = 4; + int32 fallbackTimeoutMs = 5; + string installDir = 6; + bytes tlsPolicyJSON = 7; + bool isOn = 8; + bool isDefault = 9; +} + +message DeleteHTTPDNSClusterRequest { + int64 clusterId = 1; +} + +message FindHTTPDNSClusterRequest { + int64 clusterId = 1; +} + +message FindHTTPDNSClusterResponse { + HTTPDNSCluster cluster = 1; +} + +message ListHTTPDNSClustersRequest { + int64 offset = 1; + int64 size = 2; + string keyword = 3; +} + +message ListHTTPDNSClustersResponse { + repeated HTTPDNSCluster clusters = 1; +} + +message FindAllHTTPDNSClustersRequest { +} + +message FindAllHTTPDNSClustersResponse { + repeated HTTPDNSCluster clusters = 1; +} + +message UpdateHTTPDNSClusterDefaultRequest { + int64 clusterId = 1; +} + +message ListHTTPDNSNodesWithClusterIdRequest { + int64 clusterId = 1; +} + +message ListHTTPDNSNodesWithClusterIdResponse { + repeated HTTPDNSNode nodes = 1; +} diff --git a/EdgeCommon/pkg/rpc/protos/service_httpdns_domain.proto b/EdgeCommon/pkg/rpc/protos/service_httpdns_domain.proto new file mode 100644 index 0000000..21171b9 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/service_httpdns_domain.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +import "models/model_httpdns_domain.proto"; +import "models/rpc_messages.proto"; + +service HTTPDNSDomainService { + rpc createHTTPDNSDomain (CreateHTTPDNSDomainRequest) returns (CreateHTTPDNSDomainResponse); + rpc deleteHTTPDNSDomain (DeleteHTTPDNSDomainRequest) returns (RPCSuccess); + rpc updateHTTPDNSDomainStatus (UpdateHTTPDNSDomainStatusRequest) returns (RPCSuccess); + rpc listHTTPDNSDomainsWithAppId (ListHTTPDNSDomainsWithAppIdRequest) returns (ListHTTPDNSDomainsWithAppIdResponse); +} + +message CreateHTTPDNSDomainRequest { + int64 appDbId = 1; + string domain = 2; + bool isOn = 3; +} + +message CreateHTTPDNSDomainResponse { + int64 domainId = 1; +} + +message DeleteHTTPDNSDomainRequest { + int64 domainId = 1; +} + +message UpdateHTTPDNSDomainStatusRequest { + int64 domainId = 1; + bool isOn = 2; +} + +message ListHTTPDNSDomainsWithAppIdRequest { + int64 appDbId = 1; + string keyword = 2; +} + +message ListHTTPDNSDomainsWithAppIdResponse { + repeated HTTPDNSDomain domains = 1; +} diff --git a/EdgeCommon/pkg/rpc/protos/service_httpdns_node.proto b/EdgeCommon/pkg/rpc/protos/service_httpdns_node.proto new file mode 100644 index 0000000..5cfd3e4 --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/service_httpdns_node.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +import "models/model_httpdns_node.proto"; +import "models/rpc_messages.proto"; + +service HTTPDNSNodeService { + rpc createHTTPDNSNode (CreateHTTPDNSNodeRequest) returns (CreateHTTPDNSNodeResponse); + rpc updateHTTPDNSNode (UpdateHTTPDNSNodeRequest) returns (RPCSuccess); + rpc deleteHTTPDNSNode (DeleteHTTPDNSNodeRequest) returns (RPCSuccess); + rpc findHTTPDNSNode (FindHTTPDNSNodeRequest) returns (FindHTTPDNSNodeResponse); + rpc listHTTPDNSNodes (ListHTTPDNSNodesRequest) returns (ListHTTPDNSNodesResponse); + rpc updateHTTPDNSNodeStatus (UpdateHTTPDNSNodeStatusRequest) returns (RPCSuccess); +} + +message CreateHTTPDNSNodeRequest { + int64 clusterId = 1; + string name = 2; + string installDir = 3; + bool isOn = 4; +} + +message CreateHTTPDNSNodeResponse { + int64 nodeId = 1; +} + +message UpdateHTTPDNSNodeRequest { + int64 nodeId = 1; + string name = 2; + string installDir = 3; + bool isOn = 4; +} + +message DeleteHTTPDNSNodeRequest { + int64 nodeId = 1; +} + +message FindHTTPDNSNodeRequest { + int64 nodeId = 1; +} + +message FindHTTPDNSNodeResponse { + HTTPDNSNode node = 1; +} + +message ListHTTPDNSNodesRequest { + int64 clusterId = 1; +} + +message ListHTTPDNSNodesResponse { + repeated HTTPDNSNode nodes = 1; +} + +message UpdateHTTPDNSNodeStatusRequest { + int64 nodeId = 1; + bool isUp = 2; + bool isInstalled = 3; + bool isActive = 4; + bytes statusJSON = 5; + bytes installStatusJSON = 6; +} diff --git a/EdgeCommon/pkg/rpc/protos/service_httpdns_rule.proto b/EdgeCommon/pkg/rpc/protos/service_httpdns_rule.proto new file mode 100644 index 0000000..2d23b5f --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/service_httpdns_rule.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +import "models/model_httpdns_rule.proto"; +import "models/rpc_messages.proto"; + +service HTTPDNSRuleService { + rpc createHTTPDNSCustomRule (CreateHTTPDNSCustomRuleRequest) returns (CreateHTTPDNSCustomRuleResponse); + rpc updateHTTPDNSCustomRule (UpdateHTTPDNSCustomRuleRequest) returns (RPCSuccess); + rpc deleteHTTPDNSCustomRule (DeleteHTTPDNSCustomRuleRequest) returns (RPCSuccess); + rpc updateHTTPDNSCustomRuleStatus (UpdateHTTPDNSCustomRuleStatusRequest) returns (RPCSuccess); + rpc listHTTPDNSCustomRulesWithDomainId (ListHTTPDNSCustomRulesWithDomainIdRequest) returns (ListHTTPDNSCustomRulesWithDomainIdResponse); +} + +message CreateHTTPDNSCustomRuleRequest { + HTTPDNSCustomRule rule = 1; +} + +message CreateHTTPDNSCustomRuleResponse { + int64 ruleId = 1; +} + +message UpdateHTTPDNSCustomRuleRequest { + HTTPDNSCustomRule rule = 1; +} + +message DeleteHTTPDNSCustomRuleRequest { + int64 ruleId = 1; +} + +message UpdateHTTPDNSCustomRuleStatusRequest { + int64 ruleId = 1; + bool isOn = 2; +} + +message ListHTTPDNSCustomRulesWithDomainIdRequest { + int64 domainId = 1; +} + +message ListHTTPDNSCustomRulesWithDomainIdResponse { + repeated HTTPDNSCustomRule rules = 1; +} diff --git a/EdgeCommon/pkg/rpc/protos/service_httpdns_runtime_log.proto b/EdgeCommon/pkg/rpc/protos/service_httpdns_runtime_log.proto new file mode 100644 index 0000000..7aff93a --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/service_httpdns_runtime_log.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +import "models/model_httpdns_runtime_log.proto"; + +service HTTPDNSRuntimeLogService { + rpc createHTTPDNSRuntimeLogs (CreateHTTPDNSRuntimeLogsRequest) returns (CreateHTTPDNSRuntimeLogsResponse); + rpc listHTTPDNSRuntimeLogs (ListHTTPDNSRuntimeLogsRequest) returns (ListHTTPDNSRuntimeLogsResponse); +} + +message CreateHTTPDNSRuntimeLogsRequest { + repeated HTTPDNSRuntimeLog logs = 1; +} + +message CreateHTTPDNSRuntimeLogsResponse { +} + +message ListHTTPDNSRuntimeLogsRequest { + string day = 1; + int64 clusterId = 2; + int64 nodeId = 3; + string level = 4; + string keyword = 5; + int64 offset = 6; + int64 size = 7; +} + +message ListHTTPDNSRuntimeLogsResponse { + repeated HTTPDNSRuntimeLog logs = 1; + int64 total = 2; +} diff --git a/EdgeCommon/pkg/rpc/protos/service_httpdns_sandbox.proto b/EdgeCommon/pkg/rpc/protos/service_httpdns_sandbox.proto new file mode 100644 index 0000000..5a95fbe --- /dev/null +++ b/EdgeCommon/pkg/rpc/protos/service_httpdns_sandbox.proto @@ -0,0 +1,45 @@ +syntax = "proto3"; +option go_package = "./pb"; + +package pb; + +import "models/rpc_messages.proto"; + +service HTTPDNSSandboxService { + rpc testHTTPDNSResolve (TestHTTPDNSResolveRequest) returns (TestHTTPDNSResolveResponse); +} + +message TestHTTPDNSResolveRequest { + int64 clusterId = 1; + string appId = 2; + string domain = 3; + string qtype = 4; + string clientIP = 5; + string sid = 6; + string sdkVersion = 7; + string os = 8; +} + +message HTTPDNSResolveRecord { + string type = 1; + string ip = 2; + int32 ttl = 3; + int32 weight = 4; + string line = 5; + string region = 6; +} + +message TestHTTPDNSResolveResponse { + string code = 1; + string message = 2; + string requestId = 3; + string domain = 4; + string qtype = 5; + int32 ttl = 6; + repeated HTTPDNSResolveRecord records = 7; + string clientIP = 8; + string clientRegion = 9; + string clientCarrier = 10; + string clientCountry = 11; + string summary = 12; +} diff --git a/EdgeDNS/internal/const/const.go b/EdgeDNS/internal/const/const.go index 6eea4be..bae51c9 100644 --- a/EdgeDNS/internal/const/const.go +++ b/EdgeDNS/internal/const/const.go @@ -1,7 +1,7 @@ package teaconst const ( - Version = "1.4.7" //1.3.8.2 + Version = "1.4.8" //1.3.8.2 ProductName = "Edge DNS" ProcessName = "edge-dns" diff --git a/EdgeHttpDNS/.gitignore b/EdgeHttpDNS/.gitignore new file mode 100644 index 0000000..96a2d00 --- /dev/null +++ b/EdgeHttpDNS/.gitignore @@ -0,0 +1,5 @@ +*.zip +edge-dns +configs/ +logs/ +data/ diff --git a/EdgeHttpDNS/HTTPDNS后端开发计划.md b/EdgeHttpDNS/HTTPDNS后端开发计划.md index 27c7124..9d08cd3 100644 --- a/EdgeHttpDNS/HTTPDNS后端开发计划.md +++ b/EdgeHttpDNS/HTTPDNS后端开发计划.md @@ -2,7 +2,7 @@ ## 0. 文档信息 - 目标文件:`EdgeHttpDNS/HTTPDNS后端开发计划.md` -- 交付范围:`EdgeAdmin + EdgeAPI + EdgeNode + SDK对接接口` +- 交付范围:`EdgeAdmin + EdgeAPI + EdgeHttpDNS + SDK对接接口` - 交付策略:一次性全量交付(非分阶段) - 核心约束: - 仅新协议 @@ -12,6 +12,7 @@ - 独立 `edgeHTTPDNS*` 数据表 - 新增独立节点角色 `NodeRoleHTTPDNS` - 访问日志 MySQL + ClickHouse 双写(查询优先 ClickHouse) + - 不复用智能DNS(EdgeDNS/NS)模块的 DAO/Service/Store,HTTPDNS 独立实现(可参考并复制所需能力) ## 1. 目标与成功标准 1. 将 HTTPDNS 从当前 Admin 侧 mock/store 方案落地为真实后端能力。 @@ -26,13 +27,13 @@ - 访问日志与运行日志可查询、可筛选、可分页 - 节点配置与状态可下发和回传 - 主备集群服务域名可在应用设置中配置并生效 - - EdgeNode 支持 SNI 与 Host 解耦路由,并可执行 WAF 动态验签与隐匿 SNI 转发 + - EdgeHttpDNS 支持 SNI 与 Host 解耦路由,并可执行 WAF 动态验签与隐匿 SNI 转发 ## 2. 架构与边界 ### 2.1 服务边界 1. EdgeAdmin:仅负责页面动作与 RPC 编排,不存业务状态。 2. EdgeAPI:负责数据存储、策略匹配、接口服务、日志汇聚。 -3. EdgeNode(HTTPDNS节点):负责执行解析、接收策略任务、上报运行日志/访问日志,并执行 SNI/Host 解耦路由、WAF 动态验签、隐匿 SNI 转发。 +3. EdgeHttpDNS(HTTPDNS节点):负责执行解析、上报运行日志/访问日志、接收任务。 4. SDK:手动配置应用关联主备服务域名,调用 `/resolve` 获取结果。 ### 2.2 不做项 @@ -85,13 +86,13 @@ - 日志:访问日志分页查询、运行日志分页查询 - 测试:在线解析测试调用(入参包含 appId、clusterId、domain、qtype、clientIp) -### 3.3 节点日志上报 RPC(EdgeNode -> EdgeAPI) +### 3.3 节点日志上报 RPC(EdgeHttpDNS -> EdgeAPI) 1. `CreateHTTPDNSAccessLogs`(批量) 2. `CreateHTTPDNSRuntimeLogs`(批量) 3. 幂等键:`requestId + nodeId` 4. 支持高吞吐批量提交和失败重试 -### 3.4 节点路由与 WAF 策略下发契约(EdgeAPI -> EdgeNode) +### 3.4 节点路由与 WAF 策略下发契约(EdgeAPI -> EdgeHttpDNS) 1. 下发内容最小集合: - `appId/domain/serviceDomain` - `sniMode`(固定为隐匿 SNI) @@ -168,7 +169,7 @@ - 规则变更 - 证书变更 - 路由与 WAF 策略变更 -3. EdgeNode 增加 HTTPDNS 子服务: +3. EdgeHttpDNS 增加 HTTPDNS 子服务: - 接收配置快照 - 执行解析 - 上报运行/访问日志 @@ -215,7 +216,7 @@ 2. `/resolve` 各错误码分支 3. 节点日志上报双写(MySQL+CH) 4. CH 不可用时 MySQL 回退查询 -5. EdgeAPI 策略下发 -> EdgeNode 路由/WAF 执行 -> 日志落库全链路 +5. EdgeAPI 策略下发 -> EdgeHttpDNS 路由/WAF 执行 -> 日志落库全链路 ### 9.3 回归测试 1. 智能DNS功能不受影响 @@ -228,14 +229,14 @@ 3. 自定义解析按线路返回预期 IP 4. 访问日志筛选与概要展示正确 5. 运行日志级别/字段与智能DNS一致 -6. EdgeNode 可在 SNI 与 Host 解耦场景下正确路由到目标应用 +6. EdgeHttpDNS 可在 SNI 与 Host 解耦场景下正确路由到目标应用 7. 开启 WAF 动态验签后,合法请求通过、非法签名请求被拒绝且有审计日志 ## 10. 发布与回滚 1. 发布顺序: - DB migration - EdgeAPI(DAO+RPC+resolve) - - EdgeNode(角色+上报) + - EdgeHttpDNS(角色+上报) - EdgeAdmin(RPC切换) 2. 开关控制: - `httpdns.resolve.enabled` diff --git a/EdgeHttpDNS/SNI隐匿开发计划.md b/EdgeHttpDNS/SNI隐匿开发计划.md new file mode 100644 index 0000000..ff6c205 --- /dev/null +++ b/EdgeHttpDNS/SNI隐匿开发计划.md @@ -0,0 +1,92 @@ +# SNI隐匿开发计划(HTTPDNS专项) + +## 0. 目标 +在明文网络层(DNS 与 TLS ClientHello)中不出现真实业务域名;真实业务域名仅出现在加密后的 HTTP 层(Host / :authority)中传输。 + +## 1. 固定原则 +1. 只做 SNI 隐匿能力,不引入其他无关能力描述。 +2. 客户端不走系统 DNS 解析业务域名。 +3. TLS 握手阶段不发送真实业务域名 SNI。 +4. CDN/WAF 节点必须支持“空SNI接入 + Host路由”。 +5. 真实域名只在 HTTPS 加密通道内携带。 + +## 2. 端到端链路(目标形态) +1. App 调用 SDK,请求解析业务域名。 +2. SDK 从 HTTPDNS 获取业务域名对应的“接入 IP 列表”(不是业务域名 DNS)。 +3. SDK 直连接入 IP 发起 TLS: + - SNI 置空(或不发送) + - 不出现真实业务域名 +4. TLS 建立后发起 HTTPS 请求: + - Host / :authority = 真实业务域名 +5. CDN/WAF 节点在解密后读取 Host,将流量路由到对应业务源站。 + +## 3. SDK 改造要求 +### 3.1 连接行为 +1. 提供“按 IP 直连”的请求通道。 +2. TLS 握手时固定空 SNI,不允许带真实域名。 +3. HTTP 层强制写入真实 Host / :authority。 + +### 3.2 证书校验 +1. 仍必须做证书链校验(不允许关闭 TLS 安全校验)。 +2. 证书校验目标为接入层证书(CDN/WAF 对外证书),而非业务源站证书。 + +### 3.3 多IP与容错 +1. HTTPDNS 返回多个接入 IP 时,SDK 按顺序/策略重试。 +2. 连接失败可切换下一 IP。 +3. 缓存与过期策略保持稳定,避免频繁抖动。 + +### 3.4 多端一致性 +1. Android/iOS/Flutter 需保证一致行为: + - 空 SNI + - Host 注入 + - 失败重试策略 +2. 文档与示例代码同步更新。 + +## 4. CDN/WAF 节点改造要求 +### 4.1 TLS 接入 +1. 支持无 SNI ClientHello 的 TLS 握手。 +2. 为接入域名部署有效证书(覆盖客户端连接目标)。 + +### 4.2 路由逻辑 +1. 以 Host / :authority 作为业务路由主键。 +2. 路由匹配前做标准化: + - 小写化 + - 去端口 +3. Host 未命中时返回明确错误(4xx),禁止兜底到默认站点。 + +### 4.3 回源行为 +1. 节点到源站可继续使用 HTTPS 回源。 +2. 回源主机名与证书校验按现有网关策略执行。 + +### 4.4 可观测性 +1. 增加日志字段: + - `tlsSniPresent`(是否携带 SNI) + - `host` + - `routeResult` +2. 可按“空SNI请求占比、Host路由命中率”监控。 + +## 5. 控制面(管理端)要求 +1. 页面仅展示“已启用 SNI 隐匿(空SNI)”,不提供策略切换。 +2. 集群侧需可检查“节点是否支持空SNI接入”。 +3. 发布配置时支持灰度与回滚。 + +## 6. 验收标准 +1. 抓包验证: + - DNS 明文流量中不出现真实业务域名 + - TLS ClientHello 中不出现真实业务域名 SNI +2. 请求验证: + - HTTPS 请求 Host 为真实业务域名 + - CDN/WAF 按 Host 正确路由 +3. 稳定性验证: + - 多 IP 切换成功 + - 节点故障时请求可恢复 + +## 7. 上线顺序 +1. 先升级 CDN/WAF 节点能力(空SNI接入 + Host路由)。 +2. 再升级 SDK(空SNI + Host注入)。 +3. 最后按应用灰度开启,观察指标后全量。 + +## 8. 风险与约束 +1. 若 CDN/WAF 不支持空 SNI,链路会在握手阶段失败。 +2. 若 Host 路由不严格,可能出现串站风险。 +3. 若客户端错误关闭证书校验,会引入严重安全风险。 diff --git a/EdgeHttpDNS/bin/edge-httpdns b/EdgeHttpDNS/bin/edge-httpdns new file mode 100644 index 0000000..6ce2729 Binary files /dev/null and b/EdgeHttpDNS/bin/edge-httpdns differ diff --git a/EdgeHttpDNS/build/build-all.sh b/EdgeHttpDNS/build/build-all.sh new file mode 100644 index 0000000..119d58b --- /dev/null +++ b/EdgeHttpDNS/build/build-all.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +./build.sh linux amd64 +# ./build.sh linux arm64 +# ./build.sh darwin amd64 +# ./build.sh darwin arm64 diff --git a/EdgeHttpDNS/build/build.sh b/EdgeHttpDNS/build/build.sh new file mode 100644 index 0000000..adc3efb --- /dev/null +++ b/EdgeHttpDNS/build/build.sh @@ -0,0 +1,150 @@ +#!/usr/bin/env bash +set -e + +function build() { + ROOT=$(dirname "$0") + NAME="edge-httpdns" + VERSION=$(lookup-version "$ROOT"/../internal/const/const.go) + DIST=$ROOT/"../dist/${NAME}" + OS=${1} + ARCH=${2} + + if [ -z "$OS" ]; then + echo "usage: build.sh OS ARCH" + exit 1 + fi + if [ -z "$ARCH" ]; then + echo "usage: build.sh OS ARCH" + exit 1 + fi + + ZIP_PATH=$(which zip) + if [ -z "$ZIP_PATH" ]; then + echo "we need 'zip' command to compress files" + exit 1 + fi + + echo "building v${VERSION}/${OS}/${ARCH} ..." + ZIP="${NAME}-${OS}-${ARCH}-v${VERSION}.zip" + + rm -rf "$DIST" + mkdir -p "$DIST"/bin + mkdir -p "$DIST"/configs + mkdir -p "$DIST"/logs + 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 [ ! -f "$DIST"/bin/${NAME} ]; then + echo "build failed!" + exit 1 + fi + + # delete hidden files + find "$DIST" -name ".DS_Store" -delete + find "$DIST" -name ".gitignore" -delete + + echo "zip files ..." + cd "${DIST}/../" || exit 1 + if [ -f "${ZIP}" ]; then + rm -f "${ZIP}" + fi + zip -r -X -q "${ZIP}" ${NAME}/ + rm -rf "${NAME}" + cd - || exit 1 + + 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") + re="Version[ ]+=[ ]+\"([0-9.]+)\"" + if [[ $VERSION_DATA =~ $re ]]; then + echo "${BASH_REMATCH[1]}" + else + echo "could not match version" + exit 1 + fi +} + +build "$1" "$2" diff --git a/EdgeHttpDNS/cmd/edge-httpdns/main.go b/EdgeHttpDNS/cmd/edge-httpdns/main.go new file mode 100644 index 0000000..f85e62e --- /dev/null +++ b/EdgeHttpDNS/cmd/edge-httpdns/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "fmt" + "os" + + "github.com/TeaOSLab/EdgeHttpDNS/internal/apps" + "github.com/TeaOSLab/EdgeHttpDNS/internal/configs" + teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const" + "github.com/TeaOSLab/EdgeHttpDNS/internal/nodes" +) + +func main() { + app := apps.NewAppCmd(). + Version(teaconst.Version). + Product(teaconst.ProductName). + Usage(teaconst.ProcessName + " [-v|start|stop|restart|status|service|daemon]") + + app.On("start:before", func() { + _, err := configs.LoadAPIConfig() + if err != nil { + fmt.Println("[ERROR]start failed: load config from '" + configs.ConfigFileName + "' failed: " + err.Error()) + os.Exit(1) + } + }) + + app.On("daemon", func() { + nodes.NewHTTPDNSNode().Daemon() + }) + + app.On("service", func() { + err := nodes.NewHTTPDNSNode().InstallSystemService() + if err != nil { + fmt.Println("[ERROR]install failed: " + err.Error()) + return + } + fmt.Println("done") + }) + + app.Run(func() { + nodes.NewHTTPDNSNode().Run() + }) +} diff --git a/EdgeHttpDNS/edge-httpdns.exe b/EdgeHttpDNS/edge-httpdns.exe new file mode 100644 index 0000000..b74e982 Binary files /dev/null and b/EdgeHttpDNS/edge-httpdns.exe differ diff --git a/EdgeHttpDNS/go.mod b/EdgeHttpDNS/go.mod new file mode 100644 index 0000000..5798a01 --- /dev/null +++ b/EdgeHttpDNS/go.mod @@ -0,0 +1,27 @@ +module github.com/TeaOSLab/EdgeHttpDNS + +go 1.25 + +replace github.com/TeaOSLab/EdgeCommon => ../EdgeCommon + +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 + google.golang.org/grpc v1.78.0 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/miekg/dns v1.1.72 // indirect + github.com/oschwald/geoip2-golang v1.13.0 // indirect + github.com/oschwald/maxminddb-golang v1.13.0 // 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 +) diff --git a/EdgeHttpDNS/go.sum b/EdgeHttpDNS/go.sum new file mode 100644 index 0000000..6ee1098 --- /dev/null +++ b/EdgeHttpDNS/go.sum @@ -0,0 +1,67 @@ +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/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.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= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/iwind/TeaGo v0.0.0-20240411075713-6c1fc9aca7b6 h1:dS3pTxrLlDQxdoxSUcHkHnr3LHpsBIXv8v2/xw65RN8= +github.com/iwind/TeaGo v0.0.0-20240411075713-6c1fc9aca7b6/go.mod h1:SfqVbWyIPdVflyA6lMgicZzsoGS8pyeLiTRe8/CIpGI= +github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4 h1:VWGsCqTzObdlbf7UUE3oceIpcEKi4C/YBUszQXk118A= +github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA= +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/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= +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= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +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.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= +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= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/EdgeHttpDNS/internal/apps/app_cmd.go b/EdgeHttpDNS/internal/apps/app_cmd.go new file mode 100644 index 0000000..208fd9e --- /dev/null +++ b/EdgeHttpDNS/internal/apps/app_cmd.go @@ -0,0 +1,149 @@ +package apps + +import ( + "fmt" + "os" + "os/exec" + "runtime" + "time" + + teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const" + "github.com/iwind/TeaGo/maps" + "github.com/iwind/gosock/pkg/gosock" +) + +type AppCmd struct { + product string + version string + usage string + directives map[string]func() + sock *gosock.Sock +} + +func NewAppCmd() *AppCmd { + return &AppCmd{ + directives: map[string]func(){}, + sock: gosock.NewTmpSock(teaconst.ProcessName), + } +} + +func (a *AppCmd) Product(product string) *AppCmd { + a.product = product + return a +} + +func (a *AppCmd) Version(version string) *AppCmd { + a.version = version + return a +} + +func (a *AppCmd) Usage(usage string) *AppCmd { + a.usage = usage + return a +} + +func (a *AppCmd) On(arg string, callback func()) { + a.directives[arg] = callback +} + +func (a *AppCmd) Run(main func()) { + args := os.Args[1:] + if len(args) == 0 { + main() + return + } + + switch args[0] { + case "-v", "version", "-version", "--version": + fmt.Println(a.product+" v"+a.version, "(build:", runtimeString()+")") + return + case "help", "-h", "--help": + fmt.Println(a.product + " v" + a.version) + fmt.Println("Usage:") + fmt.Println(" " + a.usage) + return + case "start": + a.runDirective("start:before") + a.runStart() + return + case "stop": + a.runStop() + return + case "restart": + a.runStop() + time.Sleep(1 * time.Second) + a.runDirective("start:before") + a.runStart() + return + case "status": + a.runStatus() + return + default: + if callback, ok := a.directives[args[0]]; ok { + callback() + return + } + fmt.Println("unknown command '" + args[0] + "'") + } +} + +func (a *AppCmd) runStart() { + pid := a.getPID() + if pid > 0 { + fmt.Println(a.product+" already started, pid:", pid) + return + } + + cmd := exec.Command(os.Args[0]) + cmd.Env = append(os.Environ(), "EdgeBackground=on") + err := cmd.Start() + if err != nil { + fmt.Println(a.product+" start failed:", err.Error()) + return + } + + fmt.Println(a.product+" started, pid:", cmd.Process.Pid) +} + +func (a *AppCmd) runStop() { + pid := a.getPID() + if pid == 0 { + fmt.Println(a.product + " not started") + return + } + + _, _ = a.sock.Send(&gosock.Command{Code: "stop"}) + fmt.Println(a.product+" stopped, pid:", pid) +} + +func (a *AppCmd) runStatus() { + pid := a.getPID() + if pid == 0 { + fmt.Println(a.product + " not started") + return + } + fmt.Println(a.product+" is running, pid:", pid) +} + +func (a *AppCmd) runDirective(name string) { + if callback, ok := a.directives[name]; ok && callback != nil { + callback() + } +} + +func (a *AppCmd) getPID() int { + if !a.sock.IsListening() { + return 0 + } + + reply, err := a.sock.Send(&gosock.Command{Code: "pid"}) + if err != nil { + return 0 + } + + return maps.NewMap(reply.Params).GetInt("pid") +} + +func runtimeString() string { + return runtime.GOOS + "/" + runtime.GOARCH +} diff --git a/EdgeHttpDNS/internal/const/const.go b/EdgeHttpDNS/internal/const/const.go new file mode 100644 index 0000000..6503055 --- /dev/null +++ b/EdgeHttpDNS/internal/const/const.go @@ -0,0 +1,23 @@ +package teaconst + +const ( + Version = "1.4.8" + + ProductName = "Edge HTTPDNS" + ProcessName = "edge-httpdns" + ProductNameZH = "Edge HTTPDNS" + + Role = "httpdns" + + EncryptKey = "8f983f4d69b83aaa0d74b21a212f6967" + EncryptMethod = "aes-256-cfb" + + SystemdServiceName = "edge-httpdns" + + // HTTPDNS node tasks from API. + TaskTypeHTTPDNSConfigChanged = "httpdnsConfigChanged" + TaskTypeHTTPDNSAppChanged = "httpdnsAppChanged" + TaskTypeHTTPDNSDomainChanged = "httpdnsDomainChanged" + TaskTypeHTTPDNSRuleChanged = "httpdnsRuleChanged" + TaskTypeHTTPDNSTLSChanged = "httpdnsTLSChanged" +) diff --git a/EdgeHttpDNS/internal/encrypt/method.go b/EdgeHttpDNS/internal/encrypt/method.go new file mode 100644 index 0000000..a297e7f --- /dev/null +++ b/EdgeHttpDNS/internal/encrypt/method.go @@ -0,0 +1,7 @@ +package encrypt + +type MethodInterface interface { + Init(key []byte, iv []byte) error + Encrypt(src []byte) (dst []byte, err error) + Decrypt(dst []byte) (src []byte, err error) +} diff --git a/EdgeHttpDNS/internal/encrypt/method_aes_256_cfb.go b/EdgeHttpDNS/internal/encrypt/method_aes_256_cfb.go new file mode 100644 index 0000000..3c3435f --- /dev/null +++ b/EdgeHttpDNS/internal/encrypt/method_aes_256_cfb.go @@ -0,0 +1,64 @@ +package encrypt + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" +) + +type AES256CFBMethod struct { + block cipher.Block + iv []byte +} + +func (m *AES256CFBMethod) Init(key, iv []byte) error { + keyLen := len(key) + if keyLen > 32 { + key = key[:32] + } else if keyLen < 32 { + key = append(key, bytes.Repeat([]byte{' '}, 32-keyLen)...) + } + + block, err := aes.NewCipher(key) + if err != nil { + return err + } + m.block = block + + ivLen := len(iv) + if ivLen > aes.BlockSize { + iv = iv[:aes.BlockSize] + } else if ivLen < aes.BlockSize { + iv = append(iv, bytes.Repeat([]byte{' '}, aes.BlockSize-ivLen)...) + } + m.iv = iv + return nil +} + +func (m *AES256CFBMethod) Encrypt(src []byte) (dst []byte, err error) { + if len(src) == 0 { + return + } + + defer func() { + err = RecoverMethodPanic(recover()) + }() + + dst = make([]byte, len(src)) + cipher.NewCFBEncrypter(m.block, m.iv).XORKeyStream(dst, src) + return +} + +func (m *AES256CFBMethod) Decrypt(dst []byte) (src []byte, err error) { + if len(dst) == 0 { + return + } + + defer func() { + err = RecoverMethodPanic(recover()) + }() + + src = make([]byte, len(dst)) + cipher.NewCFBDecrypter(m.block, m.iv).XORKeyStream(src, dst) + return +} diff --git a/EdgeHttpDNS/internal/encrypt/method_raw.go b/EdgeHttpDNS/internal/encrypt/method_raw.go new file mode 100644 index 0000000..a823cc3 --- /dev/null +++ b/EdgeHttpDNS/internal/encrypt/method_raw.go @@ -0,0 +1,15 @@ +package encrypt + +type RawMethod struct{} + +func (m *RawMethod) Init(key []byte, iv []byte) error { + return nil +} + +func (m *RawMethod) Encrypt(src []byte) (dst []byte, err error) { + return src, nil +} + +func (m *RawMethod) Decrypt(dst []byte) (src []byte, err error) { + return dst, nil +} diff --git a/EdgeHttpDNS/internal/encrypt/method_utils.go b/EdgeHttpDNS/internal/encrypt/method_utils.go new file mode 100644 index 0000000..7c4077b --- /dev/null +++ b/EdgeHttpDNS/internal/encrypt/method_utils.go @@ -0,0 +1,40 @@ +package encrypt + +import ( + "errors" + "reflect" +) + +var methods = map[string]reflect.Type{ + "raw": reflect.TypeOf(new(RawMethod)).Elem(), + "aes-256-cfb": reflect.TypeOf(new(AES256CFBMethod)).Elem(), +} + +func NewMethodInstance(method string, key string, iv string) (MethodInterface, error) { + valueType, ok := methods[method] + if !ok { + return nil, errors.New("method '" + method + "' not found") + } + + instance, ok := reflect.New(valueType).Interface().(MethodInterface) + if !ok { + return nil, errors.New("method '" + method + "' must implement MethodInterface") + } + + err := instance.Init([]byte(key), []byte(iv)) + return instance, err +} + +func RecoverMethodPanic(err interface{}) error { + if err == nil { + return nil + } + + if s, ok := err.(string); ok { + return errors.New(s) + } + if e, ok := err.(error); ok { + return e + } + return errors.New("unknown error") +} diff --git a/EdgeHttpDNS/internal/nodes/httpdns_node.go b/EdgeHttpDNS/internal/nodes/httpdns_node.go new file mode 100644 index 0000000..e799f05 --- /dev/null +++ b/EdgeHttpDNS/internal/nodes/httpdns_node.go @@ -0,0 +1,157 @@ +package nodes + +import ( + "errors" + "log" + "net" + "os" + "os/exec" + "runtime" + "sync" + "time" + + teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const" + "github.com/TeaOSLab/EdgeHttpDNS/internal/utils" + "github.com/iwind/TeaGo/maps" + "github.com/iwind/gosock/pkg/gosock" +) + +type HTTPDNSNode struct { + sock *gosock.Sock + + quitOnce sync.Once + quitCh chan struct{} +} + +func NewHTTPDNSNode() *HTTPDNSNode { + return &HTTPDNSNode{ + sock: gosock.NewTmpSock(teaconst.ProcessName), + quitCh: make(chan struct{}), + } +} + +func (n *HTTPDNSNode) Run() { + err := n.listenSock() + if err != nil { + log.Println("[HTTPDNS_NODE]" + err.Error()) + return + } + + go n.start() + select {} +} + +func (n *HTTPDNSNode) Daemon() { + path := os.TempDir() + "/" + teaconst.ProcessName + ".sock" + for { + conn, err := net.DialTimeout("unix", path, 1*time.Second) + if err != nil { + exe, exeErr := os.Executable() + if exeErr != nil { + log.Println("[DAEMON]", exeErr) + time.Sleep(1 * time.Second) + continue + } + + cmd := exec.Command(exe) + cmd.Env = append(os.Environ(), "EdgeBackground=on") + if runtime.GOOS != "windows" { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + } + startErr := cmd.Start() + if startErr != nil { + log.Println("[DAEMON]", startErr) + time.Sleep(1 * time.Second) + continue + } + _ = cmd.Wait() + time.Sleep(5 * time.Second) + continue + } + + _ = conn.Close() + time.Sleep(5 * time.Second) + } +} + +func (n *HTTPDNSNode) InstallSystemService() error { + exe, err := os.Executable() + if err != nil { + return err + } + + manager := utils.NewServiceManager(teaconst.SystemdServiceName, teaconst.ProductName) + return manager.Install(exe, []string{}) +} + +func (n *HTTPDNSNode) listenSock() error { + if runtime.GOOS == "windows" { + return nil + } + + if n.sock.IsListening() { + reply, err := n.sock.Send(&gosock.Command{Code: "pid"}) + if err == nil { + return errors.New("the process is already running, pid: " + maps.NewMap(reply.Params).GetString("pid")) + } + return errors.New("the process is already running") + } + + go func() { + n.sock.OnCommand(func(cmd *gosock.Command) { + switch cmd.Code { + case "pid": + _ = cmd.Reply(&gosock.Command{ + Code: "pid", + Params: map[string]interface{}{ + "pid": os.Getpid(), + }, + }) + case "info": + exePath, _ := os.Executable() + _ = cmd.Reply(&gosock.Command{ + Code: "info", + Params: map[string]interface{}{ + "pid": os.Getpid(), + "version": teaconst.Version, + "path": exePath, + }, + }) + case "stop": + _ = cmd.ReplyOk() + n.stop() + time.Sleep(100 * time.Millisecond) + os.Exit(0) + } + }) + + err := n.sock.Listen() + if err != nil { + log.Println("[HTTPDNS_NODE][sock]", err.Error()) + } + }() + + return nil +} + +func (n *HTTPDNSNode) start() { + log.Println("[HTTPDNS_NODE]started") + + snapshotManager := NewSnapshotManager(n.quitCh) + statusManager := NewStatusManager(n.quitCh) + taskManager := NewTaskManager(n.quitCh, snapshotManager) + resolveServer := NewResolveServer(n.quitCh, snapshotManager) + + go snapshotManager.Start() + go statusManager.Start() + go taskManager.Start() + go resolveServer.Start() +} + +func (n *HTTPDNSNode) stop() { + n.quitOnce.Do(func() { + close(n.quitCh) + _ = n.sock.Close() + }) +} diff --git a/EdgeHttpDNS/internal/nodes/resolve_server.go b/EdgeHttpDNS/internal/nodes/resolve_server.go new file mode 100644 index 0000000..0ab8440 --- /dev/null +++ b/EdgeHttpDNS/internal/nodes/resolve_server.go @@ -0,0 +1,1119 @@ +package nodes + +import ( + "context" + "crypto/hmac" + "crypto/sha256" + "crypto/tls" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "log" + "net" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "github.com/TeaOSLab/EdgeCommon/pkg/iplibrary" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeHttpDNS/internal/configs" + "github.com/TeaOSLab/EdgeHttpDNS/internal/rpc" + "github.com/iwind/TeaGo/rands" + "github.com/miekg/dns" +) + +// sharedRecursionDNSClient 共享的递归DNS客户端(对齐 EdgeDNS 实现) +var sharedRecursionDNSClient = &dns.Client{ + Timeout: 3 * time.Second, +} + +const ( + httpdnsCodeSuccess = "SUCCESS" + httpdnsCodeAppInvalid = "APP_NOT_FOUND_OR_DISABLED" + httpdnsCodeDomainNotBound = "DOMAIN_NOT_BOUND" + httpdnsCodeSignInvalid = "SIGN_INVALID" + httpdnsCodeNoRecords = "NO_RECORDS" + httpdnsCodeInternalError = "RESOLVE_TIMEOUT_OR_INTERNAL" + httpdnsCodeMethodNotAllow = "METHOD_NOT_ALLOWED" + httpdnsCodeInvalidArgument = "INVALID_ARGUMENT" +) + +type resolveClientInfo struct { + IP string `json:"ip"` + Region string `json:"region"` + Carrier string `json:"carrier"` + Country string `json:"country"` +} + +type resolveRecord struct { + Type string `json:"type"` + IP string `json:"ip"` + Weight int32 `json:"weight,omitempty"` + Line string `json:"line,omitempty"` + Region string `json:"region,omitempty"` +} + +type resolveData struct { + Domain string `json:"domain"` + QType string `json:"qtype"` + TTL int32 `json:"ttl"` + Records []*resolveRecord `json:"records"` + Client *resolveClientInfo `json:"client"` + Summary string `json:"summary"` +} + +type resolveResponse struct { + Code string `json:"code"` + Message string `json:"message"` + RequestID string `json:"requestId"` + Data *resolveData `json:"data,omitempty"` +} + +type clientRouteProfile struct { + IP string + Country string + Province string + Carrier string + ProviderRaw string + Region string + Continent string + RegionText string +} + +type ResolveServer struct { + quitCh <-chan struct{} + + snapshotManager *SnapshotManager + + listenAddr string + certFile string + keyFile string + server *http.Server + + logQueue chan *pb.HTTPDNSAccessLog +} + +func NewResolveServer(quitCh <-chan struct{}, snapshotManager *SnapshotManager) *ResolveServer { + listenAddr := ":443" + certFile := "" + keyFile := "" + if apiConfig, err := configs.SharedAPIConfig(); err == nil && apiConfig != nil { + if len(apiConfig.HTTPSListenAddr) > 0 { + listenAddr = apiConfig.HTTPSListenAddr + } + certFile = apiConfig.HTTPSCert + keyFile = apiConfig.HTTPSKey + } + + instance := &ResolveServer{ + quitCh: quitCh, + snapshotManager: snapshotManager, + listenAddr: listenAddr, + certFile: certFile, + keyFile: keyFile, + logQueue: make(chan *pb.HTTPDNSAccessLog, 8192), + } + + mux := http.NewServeMux() + mux.HandleFunc("/resolve", instance.handleResolve) + mux.HandleFunc("/healthz", instance.handleHealth) + + instance.server = &http.Server{ + Addr: instance.listenAddr, + Handler: mux, + ReadTimeout: 5 * time.Second, + ReadHeaderTimeout: 3 * time.Second, + WriteTimeout: 5 * time.Second, + IdleTimeout: 75 * time.Second, + MaxHeaderBytes: 8 * 1024, + TLSConfig: &tls.Config{ + MinVersion: tls.VersionTLS12, + }, + } + + return instance +} + +func (s *ResolveServer) Start() { + go s.startAccessLogFlusher() + go s.waitForShutdown() + + log.Println("[HTTPDNS_NODE][resolve]listening HTTPS on", s.listenAddr) + if err := s.server.ListenAndServeTLS(s.certFile, s.keyFile); err != nil && !errors.Is(err, http.ErrServerClosed) { + log.Println("[HTTPDNS_NODE][resolve]listen failed:", err.Error()) + } +} + +func (s *ResolveServer) waitForShutdown() { + <-s.quitCh + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + _ = s.server.Shutdown(ctx) +} + +func (s *ResolveServer) handleHealth(writer http.ResponseWriter, _ *http.Request) { + writer.WriteHeader(http.StatusOK) + _, _ = writer.Write([]byte("ok")) +} + +func (s *ResolveServer) handleResolve(writer http.ResponseWriter, request *http.Request) { + startAt := time.Now() + requestID := "rid-" + rands.HexString(16) + + if request.Method != http.MethodGet { + s.writeResolveJSON(writer, http.StatusMethodNotAllowed, &resolveResponse{ + Code: httpdnsCodeMethodNotAllow, + Message: "只允许使用 GET 方法", + RequestID: requestID, + }) + return + } + + query := request.URL.Query() + appID := strings.TrimSpace(query.Get("appId")) + domain := strings.TrimSuffix(strings.ToLower(strings.TrimSpace(query.Get("dn"))), ".") + qtype := strings.ToUpper(strings.TrimSpace(query.Get("qtype"))) + if len(qtype) == 0 { + qtype = "A" + } + if qtype != "A" && qtype != "AAAA" { + s.writeResolveJSON(writer, http.StatusBadRequest, &resolveResponse{ + Code: httpdnsCodeInvalidArgument, + Message: "qtype 参数仅支持 A 或 AAAA", + RequestID: requestID, + }) + return + } + + if len(appID) == 0 || len(domain) == 0 { + s.writeResolveJSON(writer, http.StatusBadRequest, &resolveResponse{ + Code: httpdnsCodeInvalidArgument, + Message: "缺少必填参数: appId 和 dn", + RequestID: requestID, + }) + return + } + + snapshot := s.snapshotManager.Current() + if snapshot == nil { + s.writeResolveJSON(writer, http.StatusServiceUnavailable, &resolveResponse{ + Code: httpdnsCodeInternalError, + Message: "服务节点尚未准备就绪,请稍后再试", + RequestID: requestID, + }) + return + } + + loadedApp := snapshot.Apps[strings.ToLower(appID)] + if loadedApp == nil || loadedApp.App == nil || !loadedApp.App.GetIsOn() { + s.writeFailedResolve(writer, requestID, snapshot, nil, domain, qtype, httpdnsCodeAppInvalid, "找不到指定的应用,或该应用已下线", startAt, request, query) + return + } + + if snapshot.ClusterID > 0 && + loadedApp.App.GetPrimaryClusterId() != snapshot.ClusterID && + loadedApp.App.GetBackupClusterId() != snapshot.ClusterID { + s.writeFailedResolve(writer, requestID, snapshot, loadedApp.App, domain, qtype, httpdnsCodeAppInvalid, "当前应用未绑定到该解析集群", startAt, request, query) + return + } + + loadedDomain := loadedApp.Domains[domain] + if loadedDomain == nil || loadedDomain.Domain == nil || !loadedDomain.Domain.GetIsOn() { + s.writeFailedResolve(writer, requestID, snapshot, loadedApp.App, domain, qtype, httpdnsCodeDomainNotBound, "应用尚未绑定该域名,或域名解析已暂停", startAt, request, query) + return + } + + if loadedApp.App.GetSignEnabled() { + if !validateResolveSign(loadedApp.App.GetSignSecret(), loadedApp.App.GetAppId(), domain, qtype, query.Get("nonce"), query.Get("exp"), query.Get("sign")) { + s.writeFailedResolve(writer, requestID, snapshot, loadedApp.App, domain, qtype, httpdnsCodeSignInvalid, "请求鉴权失败:签名无效或已过期", startAt, request, query) + return + } + } + + clientIP := detectClientIP(request, query.Get("cip")) + clientProfile := buildClientRouteProfile(clientIP) + + clusterTTL := pickDefaultTTL(snapshot, loadedApp.App) + rule, records, ttl := pickRuleRecords(loadedDomain.Rules, qtype, clientProfile, clusterTTL) + if len(records) == 0 { + // Fallback:回源上游 DNS 查询真实记录 + fallbackRecords, fallbackTTL, fallbackErr := fallbackResolve(domain, qtype) + if fallbackErr != nil || len(fallbackRecords) == 0 { + errMsg := "未找到解析记录" + if fallbackErr != nil { + errMsg = "未找到解析记录 (上游回源失败: " + fallbackErr.Error() + ")" + } + s.writeFailedResolve(writer, requestID, snapshot, loadedApp.App, domain, qtype, httpdnsCodeNoRecords, errMsg, startAt, request, query) + return + } + records = fallbackRecords + if fallbackTTL > 0 { + ttl = fallbackTTL + } else { + ttl = clusterTTL + } + } + if ttl <= 0 { + ttl = clusterTTL + } + if ttl <= 0 { + ttl = 30 + } + + resultIPs := make([]string, 0, len(records)) + for _, record := range records { + resultIPs = append(resultIPs, record.IP) + } + + summary := fmt.Sprintf("%s|%s(%s)|%s|%s %s -> %s|success|%dms", + time.Now().Format("2006-01-02 15:04:05"), + loadedApp.App.GetName(), + loadedApp.App.GetAppId(), + clientProfile.IP, + qtype, + domain, + strings.Join(resultIPs, ", "), + time.Since(startAt).Milliseconds(), + ) + if rule != nil && len(strings.TrimSpace(rule.GetRuleName())) > 0 { + summary += "|rule:" + strings.TrimSpace(rule.GetRuleName()) + } + + s.writeResolveJSON(writer, http.StatusOK, &resolveResponse{ + Code: httpdnsCodeSuccess, + Message: "ok", + RequestID: requestID, + Data: &resolveData{ + Domain: domain, + QType: qtype, + TTL: ttl, + Records: records, + Client: &resolveClientInfo{ + IP: clientProfile.IP, + Region: clientProfile.RegionText, + Carrier: clientProfile.Carrier, + Country: clientProfile.Country, + }, + Summary: summary, + }, + }) + + s.enqueueAccessLog(&pb.HTTPDNSAccessLog{ + RequestId: requestID, + ClusterId: snapshot.ClusterID, + NodeId: snapshot.NodeID, + AppId: loadedApp.App.GetAppId(), + AppName: loadedApp.App.GetName(), + Domain: domain, + Qtype: qtype, + ClientIP: clientProfile.IP, + ClientRegion: clientProfile.RegionText, + Carrier: clientProfile.Carrier, + SdkVersion: strings.TrimSpace(query.Get("sdk_version")), + Os: strings.TrimSpace(query.Get("os")), + ResultIPs: strings.Join(resultIPs, ","), + Status: "success", + ErrorCode: "none", + CostMs: int32(time.Since(startAt).Milliseconds()), + CreatedAt: time.Now().Unix(), + Day: time.Now().Format("20060102"), + Summary: summary, + }) +} + +func pickDefaultTTL(snapshot *LoadedSnapshot, app *pb.HTTPDNSApp) int32 { + if snapshot == nil { + return 30 + } + + if snapshot.ClusterID > 0 { + if cluster := snapshot.Clusters[snapshot.ClusterID]; cluster != nil && cluster.GetDefaultTTL() > 0 { + return cluster.GetDefaultTTL() + } + } + if app != nil { + if cluster := snapshot.Clusters[app.GetPrimaryClusterId()]; cluster != nil && cluster.GetDefaultTTL() > 0 { + return cluster.GetDefaultTTL() + } + if cluster := snapshot.Clusters[app.GetBackupClusterId()]; cluster != nil && cluster.GetDefaultTTL() > 0 { + return cluster.GetDefaultTTL() + } + } + return 30 +} + +func (s *ResolveServer) writeFailedResolve( + writer http.ResponseWriter, + requestID string, + snapshot *LoadedSnapshot, + app *pb.HTTPDNSApp, + domain string, + qtype string, + errorCode string, + message string, + startAt time.Time, + request *http.Request, + query url.Values, +) { + clientIP := detectClientIP(request, query.Get("cip")) + clientProfile := buildClientRouteProfile(clientIP) + + appID := "" + appName := "" + if app != nil { + appID = app.GetAppId() + appName = app.GetName() + } + + summary := fmt.Sprintf("%s|%s(%s)|%s|%s %s -> [none]|failed(%s)|%dms", + time.Now().Format("2006-01-02 15:04:05"), + appName, + appID, + clientProfile.IP, + qtype, + domain, + errorCode, + time.Since(startAt).Milliseconds(), + ) + + s.writeResolveJSON(writer, http.StatusOK, &resolveResponse{ + Code: errorCode, + Message: message, + RequestID: requestID, + }) + + clusterID := int64(0) + nodeID := int64(0) + if snapshot != nil { + clusterID = snapshot.ClusterID + nodeID = snapshot.NodeID + } + + s.enqueueAccessLog(&pb.HTTPDNSAccessLog{ + RequestId: requestID, + ClusterId: clusterID, + NodeId: nodeID, + AppId: appID, + AppName: appName, + Domain: domain, + Qtype: qtype, + ClientIP: clientProfile.IP, + ClientRegion: clientProfile.RegionText, + Carrier: clientProfile.Carrier, + SdkVersion: strings.TrimSpace(query.Get("sdk_version")), + Os: strings.TrimSpace(query.Get("os")), + ResultIPs: "", + Status: "failed", + ErrorCode: errorCode, + CostMs: int32(time.Since(startAt).Milliseconds()), + CreatedAt: time.Now().Unix(), + Day: time.Now().Format("20060102"), + Summary: summary, + }) +} + +func (s *ResolveServer) writeResolveJSON(writer http.ResponseWriter, status int, resp *resolveResponse) { + writer.Header().Set("Content-Type", "application/json; charset=utf-8") + writer.WriteHeader(status) + data, err := json.Marshal(resp) + if err != nil { + _, _ = writer.Write([]byte(`{"code":"RESOLVE_TIMEOUT_OR_INTERNAL","message":"encode response failed"}`)) + return + } + _, _ = writer.Write(data) +} + +func detectClientIP(request *http.Request, cip string) string { + if candidate := normalizeIPCandidate(cip); len(candidate) > 0 { + return candidate + } + + xff := strings.TrimSpace(request.Header.Get("X-Forwarded-For")) + if len(xff) > 0 { + for _, item := range strings.Split(xff, ",") { + if candidate := normalizeIPCandidate(item); len(candidate) > 0 { + return candidate + } + } + } + + headerKeys := []string{"X-Real-IP", "X-Client-IP", "CF-Connecting-IP", "True-Client-IP"} + for _, key := range headerKeys { + if candidate := normalizeIPCandidate(request.Header.Get(key)); len(candidate) > 0 { + return candidate + } + } + + return normalizeIPCandidate(request.RemoteAddr) +} + +func validateResolveSign(signSecret string, appID string, domain string, qtype string, nonce string, exp string, sign string) bool { + signSecret = strings.TrimSpace(signSecret) + nonce = strings.TrimSpace(nonce) + exp = strings.TrimSpace(exp) + sign = strings.TrimSpace(sign) + if len(signSecret) == 0 || len(nonce) == 0 || len(exp) == 0 || len(sign) == 0 { + return false + } + + expireAt, err := strconv.ParseInt(exp, 10, 64) + if err != nil { + return false + } + now := time.Now().Unix() + if expireAt <= now-30 || expireAt > now+86400 { + return false + } + + raw := appID + "|" + strings.ToLower(domain) + "|" + strings.ToUpper(qtype) + "|" + exp + "|" + nonce + mac := hmac.New(sha256.New, []byte(signSecret)) + _, _ = mac.Write([]byte(raw)) + expected := hex.EncodeToString(mac.Sum(nil)) + return strings.EqualFold(expected, sign) +} + +func buildClientRouteProfile(ip string) *clientRouteProfile { + profile := &clientRouteProfile{ + IP: normalizeIPCandidate(ip), + } + if net.ParseIP(profile.IP) == nil { + return profile + } + + result := iplibrary.LookupIP(profile.IP) + if result == nil || !result.IsOk() { + return profile + } + + profile.Country = normalizeCountryName(strings.TrimSpace(result.CountryName())) + profile.Province = normalizeProvinceName(strings.TrimSpace(result.ProvinceName())) + profile.ProviderRaw = strings.TrimSpace(result.ProviderName()) + profile.Carrier = normalizeCarrier(profile.ProviderRaw, profile.Country) + if len(profile.Carrier) == 0 { + if isMainlandChinaCountry(profile.Country) { + profile.Carrier = "默认" + } else { + if len(profile.ProviderRaw) > 0 { + profile.Carrier = profile.ProviderRaw + } else { + profile.Carrier = "默认" + } + } + } + profile.Region = normalizeChinaRegion(profile.Province) + profile.Continent = normalizeContinent(profile.Country) + profile.RegionText = strings.TrimSpace(result.RegionSummary()) + if len(profile.RegionText) == 0 { + pieces := make([]string, 0, 4) + if len(profile.Country) > 0 { + pieces = append(pieces, profile.Country) + } + if len(profile.Province) > 0 { + pieces = append(pieces, profile.Province) + } + if len(profile.Region) > 0 { + pieces = append(pieces, profile.Region) + } + if len(profile.Carrier) > 0 { + pieces = append(pieces, profile.Carrier) + } + profile.RegionText = strings.Join(pieces, " ") + } + + return profile +} + +func normalizeCarrier(provider string, country string) string { + value := strings.TrimSpace(provider) + if len(value) == 0 { + return "" + } + lower := strings.ToLower(value) + switch { + case strings.Contains(value, "电信"), strings.Contains(value, "天翼"), + strings.Contains(lower, "telecom"), strings.Contains(lower, "chinanet"), + strings.Contains(lower, "chinatelecom"), strings.Contains(lower, "ctnet"), strings.Contains(lower, "cn2"): + return "电信" + case strings.Contains(value, "联通"), strings.Contains(value, "网通"), + strings.Contains(lower, "unicom"), strings.Contains(lower, "chinaunicom"), + strings.Contains(lower, "cucc"), strings.Contains(lower, "china169"), strings.Contains(lower, "cnc"): + return "联通" + case strings.Contains(value, "移动"), + strings.Contains(lower, "mobile"), strings.Contains(lower, "chinamobile"), + strings.Contains(lower, "cmcc"), strings.Contains(lower, "cmnet"): + return "移动" + case strings.Contains(value, "教育"), + strings.Contains(lower, "cernet"), strings.Contains(lower, "edu"), strings.Contains(lower, "education"): + return "教育网" + case strings.Contains(value, "鹏博士"), + strings.Contains(lower, "drpeng"), strings.Contains(lower, "dr.peng"), strings.Contains(lower, "dr_peng"): + return "鹏博士" + case strings.Contains(value, "广电"), + strings.Contains(lower, "broadcast"), strings.Contains(lower, "cable"), strings.Contains(lower, "radio"): + return "广电" + default: + if isMainlandChinaCountry(country) { + return "" + } + return value + } +} + +func normalizeChinaRegion(province string) string { + switch normalizeProvinceName(province) { + case "辽宁", "吉林", "黑龙江": + return "东北" + case "北京", "天津", "河北", "山西", "内蒙古": + return "华北" + case "上海", "江苏", "浙江", "安徽", "福建", "江西", "山东": + return "华东" + case "广东", "广西", "海南": + return "华南" + case "河南", "湖北", "湖南": + return "华中" + case "陕西", "甘肃", "青海", "宁夏", "新疆": + return "西北" + case "重庆", "四川", "贵州", "云南", "西藏": + return "西南" + default: + return "" + } +} + +func normalizeContinent(country string) string { + switch normalizeCountryName(country) { + case "中国", "中国香港", "中国澳门", "中国台湾", "日本", "韩国", "新加坡", "印度", "泰国", "越南": + return "亚洲" + case "美国", "加拿大", "墨西哥": + return "北美洲" + case "巴西", "阿根廷", "智利", "哥伦比亚": + return "南美洲" + case "德国", "英国", "法国", "荷兰", "西班牙", "意大利", "俄罗斯": + return "欧洲" + case "南非", "埃及", "尼日利亚", "肯尼亚", "摩洛哥": + return "非洲" + case "澳大利亚", "新西兰": + return "大洋洲" + default: + return "" + } +} +func pickRuleRecords(rules []*pb.HTTPDNSCustomRule, qtype string, profile *clientRouteProfile, defaultTTL int32) (*pb.HTTPDNSCustomRule, []*resolveRecord, int32) { + bestScore := -1 + var bestRule *pb.HTTPDNSCustomRule + var bestRecords []*resolveRecord + bestTTL := defaultTTL + + for _, rule := range rules { + if rule == nil || !rule.GetIsOn() { + continue + } + + score, ok := matchRuleLine(rule, profile) + if !ok { + continue + } + + records := make([]*resolveRecord, 0) + for _, item := range rule.GetRecords() { + if item == nil { + continue + } + if strings.ToUpper(strings.TrimSpace(item.GetRecordType())) != qtype { + continue + } + value := strings.TrimSpace(item.GetRecordValue()) + if len(value) == 0 { + continue + } + records = append(records, &resolveRecord{ + Type: qtype, + IP: value, + Weight: item.GetWeight(), + Line: ruleLineSummary(rule), + Region: ruleRegionSummary(rule), + }) + } + if len(records) == 0 { + continue + } + + if score > bestScore { + bestScore = score + bestRule = rule + bestRecords = records + if rule.GetTtl() > 0 { + bestTTL = rule.GetTtl() + } else { + bestTTL = defaultTTL + } + } + } + + return bestRule, bestRecords, bestTTL +} + +// fallbackResolve 当无自定义规则命中时,回源上游 DNS 查询真实记录(对齐 EdgeDNS 做法) +func fallbackResolve(domain string, qtype string) ([]*resolveRecord, int32, error) { + var dnsType uint16 + switch qtype { + case "A": + dnsType = dns.TypeA + case "AAAA": + dnsType = dns.TypeAAAA + default: + return nil, 0, nil // 仅降级处理 A 和 AAAA + } + + m := new(dns.Msg) + m.SetQuestion(dns.Fqdn(domain), dnsType) + m.RecursionDesired = true + + // 优先使用本机 /etc/resolv.conf 中的 DNS 服务器(对齐 EdgeDNS) + var upstream = "223.5.5.5:53" + resolveConfig, confErr := dns.ClientConfigFromFile("/etc/resolv.conf") + if confErr == nil && len(resolveConfig.Servers) > 0 { + port := resolveConfig.Port + if len(port) == 0 { + port = "53" + } + server := resolveConfig.Servers[rands.Int(0, len(resolveConfig.Servers)-1)] + upstream = server + ":" + port + } + + r, _, err := sharedRecursionDNSClient.Exchange(m, upstream) + if err != nil { + return nil, 0, err + } + + if r.Rcode != dns.RcodeSuccess { + return nil, 0, fmt.Errorf("upstream rcode: %d", r.Rcode) + } + + var records []*resolveRecord + var responseTTL int32 + for _, ans := range r.Answer { + switch t := ans.(type) { + case *dns.A: + if qtype == "A" { + if t.Hdr.Ttl > 0 { + ttl := int32(t.Hdr.Ttl) + if responseTTL == 0 || ttl < responseTTL { + responseTTL = ttl + } + } + ip := t.A.String() + records = append(records, &resolveRecord{ + Type: "A", + IP: ip, + Line: lookupIPLineLabel(ip), + Region: lookupIPRegionSummary(ip), + }) + } + case *dns.AAAA: + if qtype == "AAAA" { + if t.Hdr.Ttl > 0 { + ttl := int32(t.Hdr.Ttl) + if responseTTL == 0 || ttl < responseTTL { + responseTTL = ttl + } + } + ip := t.AAAA.String() + records = append(records, &resolveRecord{ + Type: "AAAA", + IP: ip, + Line: lookupIPLineLabel(ip), + Region: lookupIPRegionSummary(ip), + }) + } + } + } + + return records, responseTTL, nil +} + +func lookupIPRegionSummary(ip string) string { + address := strings.TrimSpace(ip) + if len(address) == 0 || net.ParseIP(address) == nil { + return "" + } + + result := iplibrary.LookupIP(address) + if result == nil || !result.IsOk() { + return "" + } + + return strings.TrimSpace(result.RegionSummary()) +} + +func lookupIPLineLabel(ip string) string { + address := strings.TrimSpace(ip) + if len(address) == 0 || net.ParseIP(address) == nil { + return "上游DNS" + } + + result := iplibrary.LookupIP(address) + if result == nil || !result.IsOk() { + return "上游DNS" + } + + provider := strings.TrimSpace(result.ProviderName()) + country := normalizeCountryName(strings.TrimSpace(result.CountryName())) + carrier := strings.TrimSpace(normalizeCarrier(provider, country)) + if isMainlandChinaCountry(country) { + if len(carrier) > 0 { + return carrier + } + return "默认" + } + + if len(carrier) > 0 { + return carrier + } + if len(provider) > 0 { + return provider + } + return "上游DNS" +} + +func isMainlandChinaCountry(country string) bool { + switch normalizeCountryName(country) { + case "中国": + return true + } + return false +} + +func matchRuleLine(rule *pb.HTTPDNSCustomRule, profile *clientRouteProfile) (int, bool) { + scope := strings.ToLower(strings.TrimSpace(rule.GetLineScope())) + score := 0 + + if scope == "overseas" { + // 境外规则只匹配非中国大陆来源 + if isMainlandChinaCountry(profile.Country) { + return 0, false + } + + fieldScore, ok := matchRuleField(rule.GetLineContinent(), profile.Continent) + if !ok { + return 0, false + } + score += fieldScore + + fieldScore, ok = matchRuleField(rule.GetLineCountry(), profile.Country) + if !ok { + return 0, false + } + score += fieldScore + return score, true + } + + // 中国地区规则只匹配中国大陆来源 + if !isMainlandChinaCountry(profile.Country) { + return 0, false + } + + fieldScore, ok := matchRuleField(rule.GetLineCountry(), profile.Country) + if !ok { + return 0, false + } + score += fieldScore + + fieldScore, ok = matchRuleField(rule.GetLineContinent(), profile.Continent) + if !ok { + return 0, false + } + score += fieldScore + + fieldScore, ok = matchRuleField(rule.GetLineCarrier(), profile.Carrier, profile.ProviderRaw) + if !ok { + return 0, false + } + score += fieldScore + + fieldScore, ok = matchRuleField(rule.GetLineRegion(), profile.Region) + if !ok { + return 0, false + } + score += fieldScore + + fieldScore, ok = matchRuleField(rule.GetLineProvince(), profile.Province) + if !ok { + return 0, false + } + score += fieldScore + + return score, true +} + +func matchRuleField(ruleValue string, candidates ...string) (int, bool) { + if isDefaultLineValue(ruleValue) { + return 0, true + } + + want := normalizeLineValue(ruleValue) + if len(want) == 0 { + return 0, true + } + + for _, candidate := range candidates { + got := normalizeLineValue(candidate) + if len(got) == 0 { + // 如果规则设了具体值(want),但客户端信息(got)为空,则不能匹配 + // 否则 strings.Contains("xxx", "") 永远为 true + continue + } + if want == got || strings.Contains(got, want) || strings.Contains(want, got) { + return 1, true + } + } + return 0, false +} + +func isDefaultLineValue(value string) bool { + switch normalizeLineValue(value) { + case "", "default", "all", "*", "any", "默认", "全部", "不限": + return true + } + return false +} + +func normalizeLineValue(value string) string { + v := strings.ToLower(strings.TrimSpace(value)) + v = strings.ReplaceAll(v, " ", "") + v = strings.ReplaceAll(v, "-", "") + v = strings.ReplaceAll(v, "_", "") + v = strings.ReplaceAll(v, "/", "") + return v +} + +func normalizeIPCandidate(ip string) string { + value := strings.TrimSpace(ip) + if len(value) == 0 { + return "" + } + if host, _, err := net.SplitHostPort(value); err == nil { + value = strings.TrimSpace(host) + } + if parsed := net.ParseIP(value); parsed != nil { + return parsed.String() + } + return "" +} + +func normalizeCountryName(country string) string { + value := strings.TrimSpace(country) + if len(value) == 0 { + return "" + } + + normalized := normalizeLineValue(value) + switch normalized { + case "中国香港", "香港", "hongkong": + return "中国香港" + case "中国澳门", "澳门", "macao", "macau": + return "中国澳门" + case "中国台湾", "台湾", "taiwan": + return "中国台湾" + } + + switch normalized { + case "中国", "中国大陆", "中国内地", "中华人民共和国", "prc", "cn", "china", "mainlandchina", "peoplesrepublicofchina", "thepeoplesrepublicofchina": + return "中国" + case "美国", "usa", "unitedstates", "unitedstatesofamerica": + return "美国" + case "加拿大", "canada": + return "加拿大" + case "墨西哥", "mexico": + return "墨西哥" + case "日本", "japan": + return "日本" + case "韩国", "southkorea", "korea": + return "韩国" + case "新加坡", "singapore": + return "新加坡" + case "印度", "india": + return "印度" + case "泰国", "thailand": + return "泰国" + case "越南", "vietnam": + return "越南" + case "德国", "germany": + return "德国" + case "英国", "uk", "unitedkingdom", "greatbritain", "britain": + return "英国" + case "法国", "france": + return "法国" + case "荷兰", "netherlands": + return "荷兰" + case "西班牙", "spain": + return "西班牙" + case "意大利", "italy": + return "意大利" + case "俄罗斯", "russia": + return "俄罗斯" + case "巴西", "brazil": + return "巴西" + case "阿根廷", "argentina": + return "阿根廷" + case "智利", "chile": + return "智利" + case "哥伦比亚", "colombia": + return "哥伦比亚" + case "南非", "southafrica": + return "南非" + case "埃及", "egypt": + return "埃及" + case "尼日利亚", "nigeria": + return "尼日利亚" + case "肯尼亚", "kenya": + return "肯尼亚" + case "摩洛哥", "morocco": + return "摩洛哥" + case "澳大利亚", "australia": + return "澳大利亚" + case "新西兰", "newzealand": + return "新西兰" + default: + return value + } +} + +func normalizeProvinceName(province string) string { + value := strings.TrimSpace(province) + if len(value) == 0 { + return "" + } + + switch value { + case "内蒙古自治区": + return "内蒙古" + case "广西壮族自治区": + return "广西" + case "宁夏回族自治区": + return "宁夏" + case "新疆维吾尔自治区": + return "新疆" + case "西藏自治区": + return "西藏" + case "香港特别行政区": + return "香港" + case "澳门特别行政区": + return "澳门" + } + + for _, suffix := range []string{"维吾尔自治区", "回族自治区", "壮族自治区", "自治区", "特别行政区", "省", "市"} { + value = strings.TrimSuffix(value, suffix) + } + + return value +} + +func ruleLineSummary(rule *pb.HTTPDNSCustomRule) string { + if rule == nil { + return "" + } + + scope := strings.ToLower(strings.TrimSpace(rule.GetLineScope())) + if scope == "overseas" { + pieces := make([]string, 0, 2) + if !isDefaultLineValue(rule.GetLineContinent()) { + pieces = append(pieces, strings.TrimSpace(rule.GetLineContinent())) + } + if !isDefaultLineValue(rule.GetLineCountry()) { + pieces = append(pieces, strings.TrimSpace(rule.GetLineCountry())) + } + return strings.Join(pieces, "/") + } + + pieces := make([]string, 0, 3) + if !isDefaultLineValue(rule.GetLineCarrier()) { + pieces = append(pieces, strings.TrimSpace(rule.GetLineCarrier())) + } + if !isDefaultLineValue(rule.GetLineRegion()) { + pieces = append(pieces, strings.TrimSpace(rule.GetLineRegion())) + } + if !isDefaultLineValue(rule.GetLineProvince()) { + pieces = append(pieces, strings.TrimSpace(rule.GetLineProvince())) + } + return strings.Join(pieces, "/") +} + +func ruleRegionSummary(rule *pb.HTTPDNSCustomRule) string { + if rule == nil { + return "" + } + if !isDefaultLineValue(rule.GetLineProvince()) { + return strings.TrimSpace(rule.GetLineProvince()) + } + if !isDefaultLineValue(rule.GetLineCountry()) { + return strings.TrimSpace(rule.GetLineCountry()) + } + if !isDefaultLineValue(rule.GetLineRegion()) { + return strings.TrimSpace(rule.GetLineRegion()) + } + if !isDefaultLineValue(rule.GetLineContinent()) { + return strings.TrimSpace(rule.GetLineContinent()) + } + return "" +} + +func (s *ResolveServer) enqueueAccessLog(item *pb.HTTPDNSAccessLog) { + if item == nil { + return + } + select { + case s.logQueue <- item: + default: + log.Println("[HTTPDNS_NODE][resolve]access log queue is full, drop request:", item.GetRequestId()) + } +} + +func (s *ResolveServer) startAccessLogFlusher() { + ticker := time.NewTicker(1 * time.Second) + defer ticker.Stop() + + batch := make([]*pb.HTTPDNSAccessLog, 0, 128) + flush := func() { + if len(batch) == 0 { + return + } + rpcClient, err := rpc.SharedRPC() + if err != nil { + log.Println("[HTTPDNS_NODE][resolve]access-log rpc unavailable:", err.Error()) + return + } + _, err = rpcClient.HTTPDNSAccessLogRPC.CreateHTTPDNSAccessLogs(rpcClient.Context(), &pb.CreateHTTPDNSAccessLogsRequest{ + Logs: batch, + }) + if err != nil { + log.Println("[HTTPDNS_NODE][resolve]flush access logs failed:", err.Error()) + return + } + batch = batch[:0] + } + + for { + select { + case item := <-s.logQueue: + if item != nil { + batch = append(batch, item) + } + if len(batch) > 4096 { + log.Println("[HTTPDNS_NODE][resolve]access log flush backlog too large, trim:", len(batch)) + batch = batch[len(batch)-2048:] + } + if len(batch) >= 128 { + flush() + } + case <-ticker.C: + flush() + case <-s.quitCh: + flush() + return + } + } +} diff --git a/EdgeHttpDNS/internal/nodes/runtime_log.go b/EdgeHttpDNS/internal/nodes/runtime_log.go new file mode 100644 index 0000000..ad6ca39 --- /dev/null +++ b/EdgeHttpDNS/internal/nodes/runtime_log.go @@ -0,0 +1,39 @@ +package nodes + +import ( + "log" + "time" + + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeHttpDNS/internal/rpc" +) + +func reportRuntimeLog(level string, logType string, module string, description string, requestID string) { + rpcClient, err := rpc.SharedRPC() + if err != nil { + log.Println("[HTTPDNS_NODE][runtime-log]", err.Error()) + return + } + + nodeID := int64(0) + + now := time.Now() + _, err = rpcClient.HTTPDNSRuntimeLogRPC.CreateHTTPDNSRuntimeLogs(rpcClient.Context(), &pb.CreateHTTPDNSRuntimeLogsRequest{ + Logs: []*pb.HTTPDNSRuntimeLog{ + { + NodeId: nodeID, + Level: level, + Type: logType, + Module: module, + Description: description, + Count: 1, + RequestId: requestID, + CreatedAt: now.Unix(), + Day: now.Format("20060102"), + }, + }, + }) + if err != nil { + log.Println("[HTTPDNS_NODE][runtime-log]", err.Error()) + } +} diff --git a/EdgeHttpDNS/internal/nodes/snapshot_manager.go b/EdgeHttpDNS/internal/nodes/snapshot_manager.go new file mode 100644 index 0000000..07e3041 --- /dev/null +++ b/EdgeHttpDNS/internal/nodes/snapshot_manager.go @@ -0,0 +1,160 @@ +package nodes + +import ( + "fmt" + "log" + "strings" + "sync" + "time" + + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeHttpDNS/internal/rpc" +) + +type LoadedDomain struct { + Domain *pb.HTTPDNSDomain + Rules []*pb.HTTPDNSCustomRule +} + +type LoadedApp struct { + App *pb.HTTPDNSApp + Domains map[string]*LoadedDomain // key: lower(domain) +} + +type LoadedSnapshot struct { + LoadedAt int64 + + NodeID int64 + ClusterID int64 + + Clusters map[int64]*pb.HTTPDNSCluster + Apps map[string]*LoadedApp // key: lower(appId) +} + +type SnapshotManager struct { + quitCh <-chan struct{} + ticker *time.Ticker + + locker sync.RWMutex + snapshot *LoadedSnapshot +} + +func NewSnapshotManager(quitCh <-chan struct{}) *SnapshotManager { + return &SnapshotManager{ + quitCh: quitCh, + ticker: time.NewTicker(30 * time.Second), + } +} + +func (m *SnapshotManager) Start() { + defer m.ticker.Stop() + + if err := m.RefreshNow("startup"); err != nil { + log.Println("[HTTPDNS_NODE][snapshot]initial refresh failed:", err.Error()) + } + + for { + select { + case <-m.ticker.C: + if err := m.RefreshNow("periodic"); err != nil { + log.Println("[HTTPDNS_NODE][snapshot]periodic refresh failed:", err.Error()) + } + case <-m.quitCh: + return + } + } +} + +func (m *SnapshotManager) Current() *LoadedSnapshot { + m.locker.RLock() + defer m.locker.RUnlock() + return m.snapshot +} + +func (m *SnapshotManager) RefreshNow(reason string) error { + rpcClient, err := rpc.SharedRPC() + if err != nil { + return err + } + + nodeResp, err := rpcClient.HTTPDNSNodeRPC.FindHTTPDNSNode(rpcClient.Context(), &pb.FindHTTPDNSNodeRequest{ + NodeId: 0, + }) + if err != nil { + return err + } + if nodeResp.GetNode() == nil { + return fmt.Errorf("httpdns node info not found") + } + + clusterResp, err := rpcClient.HTTPDNSClusterRPC.FindAllHTTPDNSClusters(rpcClient.Context(), &pb.FindAllHTTPDNSClustersRequest{}) + if err != nil { + return err + } + clusters := map[int64]*pb.HTTPDNSCluster{} + for _, cluster := range clusterResp.GetClusters() { + if cluster == nil || cluster.GetId() <= 0 { + continue + } + clusters[cluster.GetId()] = cluster + } + + appResp, err := rpcClient.HTTPDNSAppRPC.FindAllHTTPDNSApps(rpcClient.Context(), &pb.FindAllHTTPDNSAppsRequest{}) + if err != nil { + return err + } + + apps := map[string]*LoadedApp{} + for _, app := range appResp.GetApps() { + if app == nil || app.GetId() <= 0 || len(app.GetAppId()) == 0 { + continue + } + + domainResp, err := rpcClient.HTTPDNSDomainRPC.ListHTTPDNSDomainsWithAppId(rpcClient.Context(), &pb.ListHTTPDNSDomainsWithAppIdRequest{ + AppDbId: app.GetId(), + }) + if err != nil { + log.Println("[HTTPDNS_NODE][snapshot]list domains failed, appId:", app.GetAppId(), "err:", err.Error()) + continue + } + + domains := map[string]*LoadedDomain{} + for _, domain := range domainResp.GetDomains() { + if domain == nil || domain.GetId() <= 0 || len(domain.GetDomain()) == 0 { + continue + } + ruleResp, err := rpcClient.HTTPDNSRuleRPC.ListHTTPDNSCustomRulesWithDomainId(rpcClient.Context(), &pb.ListHTTPDNSCustomRulesWithDomainIdRequest{ + DomainId: domain.GetId(), + }) + if err != nil { + log.Println("[HTTPDNS_NODE][snapshot]list rules failed, domain:", domain.GetDomain(), "err:", err.Error()) + continue + } + + domains[strings.ToLower(strings.TrimSpace(domain.GetDomain()))] = &LoadedDomain{ + Domain: domain, + Rules: ruleResp.GetRules(), + } + } + + apps[strings.ToLower(strings.TrimSpace(app.GetAppId()))] = &LoadedApp{ + App: app, + Domains: domains, + } + } + + snapshot := &LoadedSnapshot{ + LoadedAt: time.Now().Unix(), + NodeID: nodeResp.GetNode().GetId(), + ClusterID: nodeResp.GetNode().GetClusterId(), + Clusters: clusters, + Apps: apps, + } + + m.locker.Lock() + m.snapshot = snapshot + m.locker.Unlock() + + reportRuntimeLog("info", "config", "snapshot", "snapshot refreshed: "+reason, fmt.Sprintf("snapshot-%d", time.Now().UnixNano())) + return nil +} diff --git a/EdgeHttpDNS/internal/nodes/status_manager.go b/EdgeHttpDNS/internal/nodes/status_manager.go new file mode 100644 index 0000000..2a3c159 --- /dev/null +++ b/EdgeHttpDNS/internal/nodes/status_manager.go @@ -0,0 +1,144 @@ +package nodes + +import ( + "encoding/json" + "log" + "os" + "runtime" + "strconv" + "strings" + "time" + + "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeHttpDNS/internal/configs" + teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const" + "github.com/TeaOSLab/EdgeHttpDNS/internal/rpc" + "github.com/TeaOSLab/EdgeHttpDNS/internal/utils" +) + + +type StatusManager struct { + quitCh <-chan struct{} + ticker *time.Ticker +} + +func NewStatusManager(quitCh <-chan struct{}) *StatusManager { + return &StatusManager{ + quitCh: quitCh, + ticker: time.NewTicker(30 * time.Second), + } +} + +func (m *StatusManager) Start() { + defer m.ticker.Stop() + + m.update() + for { + select { + case <-m.ticker.C: + m.update() + case <-m.quitCh: + return + } + } +} + +func (m *StatusManager) update() { + status := m.collectStatus() + statusJSON, err := json.Marshal(status) + if err != nil { + log.Println("[HTTPDNS_NODE][status]marshal status failed:", err.Error()) + return + } + + rpcClient, err := rpc.SharedRPC() + if err != nil { + log.Println("[HTTPDNS_NODE][status]rpc unavailable:", err.Error()) + return + } + + config, err := configs.SharedAPIConfig() + if err != nil { + log.Println("[HTTPDNS_NODE][status]load config failed:", err.Error()) + return + } + nodeId, _ := strconv.ParseInt(config.NodeId, 10, 64) + + _, err = rpcClient.HTTPDNSNodeRPC.UpdateHTTPDNSNodeStatus(rpcClient.Context(), &pb.UpdateHTTPDNSNodeStatusRequest{ + NodeId: nodeId, + IsUp: true, + IsInstalled: true, + IsActive: true, + StatusJSON: statusJSON, + }) + + if err != nil { + log.Println("[HTTPDNS_NODE][status]update status failed:", err.Error()) + } +} + +func (m *StatusManager) collectStatus() *nodeconfigs.NodeStatus { + now := time.Now().Unix() + + status := &nodeconfigs.NodeStatus{ + BuildVersion: teaconst.Version, + BuildVersionCode: utils.VersionToLong(teaconst.Version), + ConfigVersion: 0, + OS: runtime.GOOS, + Arch: runtime.GOARCH, + CPULogicalCount: runtime.NumCPU(), + CPUPhysicalCount: runtime.NumCPU(), + IsActive: true, + ConnectionCount: 0, + UpdatedAt: now, + Timestamp: now, + } + + rpcClient, err := rpc.SharedRPC() + if err == nil { + total, failed, avgCostSeconds := rpcClient.GetAndResetMetrics() + if total > 0 { + status.APISuccessPercent = float64(total-failed) * 100.0 / float64(total) + status.APIAvgCostSeconds = avgCostSeconds + } + } + + + 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) + } + + load1m, load5m, load15m := readLoadAvg() + status.Load1m = load1m + status.Load5m = load5m + status.Load15m = load15m + + return status +} + +func readLoadAvg() (float64, float64, float64) { + data, err := os.ReadFile("/proc/loadavg") + if err != nil { + return 0, 0, 0 + } + + parts := strings.Fields(strings.TrimSpace(string(data))) + if len(parts) < 3 { + return 0, 0, 0 + } + + load1m, _ := strconv.ParseFloat(parts[0], 64) + load5m, _ := strconv.ParseFloat(parts[1], 64) + load15m, _ := strconv.ParseFloat(parts[2], 64) + return load1m, load5m, load15m +} diff --git a/EdgeHttpDNS/internal/nodes/task_manager.go b/EdgeHttpDNS/internal/nodes/task_manager.go new file mode 100644 index 0000000..f11a6af --- /dev/null +++ b/EdgeHttpDNS/internal/nodes/task_manager.go @@ -0,0 +1,131 @@ +package nodes + +import ( + "fmt" + "log" + "time" + + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const" + "github.com/TeaOSLab/EdgeHttpDNS/internal/rpc" +) + +type TaskManager struct { + quitCh <-chan struct{} + ticker *time.Ticker + version int64 + + snapshotManager *SnapshotManager +} + +func NewTaskManager(quitCh <-chan struct{}, snapshotManager *SnapshotManager) *TaskManager { + return &TaskManager{ + quitCh: quitCh, + ticker: time.NewTicker(20 * time.Second), + version: 0, + snapshotManager: snapshotManager, + } +} + +func (m *TaskManager) Start() { + defer m.ticker.Stop() + + m.processTasks() + for { + select { + case <-m.ticker.C: + m.processTasks() + case <-m.quitCh: + return + } + } +} + +func (m *TaskManager) processTasks() { + rpcClient, err := rpc.SharedRPC() + if err != nil { + log.Println("[HTTPDNS_NODE][task]rpc unavailable:", err.Error()) + return + } + + resp, err := rpcClient.NodeTaskRPC.FindNodeTasks(rpcClient.Context(), &pb.FindNodeTasksRequest{ + Version: m.version, + }) + if err != nil { + log.Println("[HTTPDNS_NODE][task]fetch tasks failed:", err.Error()) + return + } + + for _, task := range resp.GetNodeTasks() { + ok, errorMessage := m.handleTask(task) + + _, reportErr := rpcClient.NodeTaskRPC.ReportNodeTaskDone(rpcClient.Context(), &pb.ReportNodeTaskDoneRequest{ + NodeTaskId: task.GetId(), + IsOk: ok, + Error: errorMessage, + }) + if reportErr != nil { + log.Println("[HTTPDNS_NODE][task]report task result failed:", reportErr.Error()) + } + + if task.GetVersion() > m.version { + m.version = task.GetVersion() + } + } +} + +func (m *TaskManager) handleTask(task *pb.NodeTask) (bool, string) { + taskType := task.GetType() + requestID := fmt.Sprintf("task-%d", task.GetId()) + + switch taskType { + case teaconst.TaskTypeHTTPDNSConfigChanged: + if m.snapshotManager != nil { + if err := m.snapshotManager.RefreshNow(taskType); err != nil { + reportRuntimeLog("error", "config", "task-manager", "refresh snapshot failed: "+err.Error(), requestID) + return false, err.Error() + } + } + reportRuntimeLog("info", "config", "task-manager", "HTTPDNS configuration updated", requestID) + return true, "" + case teaconst.TaskTypeHTTPDNSAppChanged: + if m.snapshotManager != nil { + if err := m.snapshotManager.RefreshNow(taskType); err != nil { + reportRuntimeLog("error", "app", "task-manager", "refresh snapshot failed: "+err.Error(), requestID) + return false, err.Error() + } + } + reportRuntimeLog("info", "app", "task-manager", "HTTPDNS app policy updated", requestID) + return true, "" + case teaconst.TaskTypeHTTPDNSDomainChanged: + if m.snapshotManager != nil { + if err := m.snapshotManager.RefreshNow(taskType); err != nil { + reportRuntimeLog("error", "domain", "task-manager", "refresh snapshot failed: "+err.Error(), requestID) + return false, err.Error() + } + } + reportRuntimeLog("info", "domain", "task-manager", "HTTPDNS domain binding updated", requestID) + return true, "" + case teaconst.TaskTypeHTTPDNSRuleChanged: + if m.snapshotManager != nil { + if err := m.snapshotManager.RefreshNow(taskType); err != nil { + reportRuntimeLog("error", "rule", "task-manager", "refresh snapshot failed: "+err.Error(), requestID) + return false, err.Error() + } + } + reportRuntimeLog("info", "rule", "task-manager", "HTTPDNS custom rule updated", requestID) + return true, "" + case teaconst.TaskTypeHTTPDNSTLSChanged: + if m.snapshotManager != nil { + if err := m.snapshotManager.RefreshNow(taskType); err != nil { + reportRuntimeLog("error", "tls", "task-manager", "refresh snapshot failed: "+err.Error(), requestID) + return false, err.Error() + } + } + reportRuntimeLog("info", "tls", "task-manager", "HTTPDNS TLS config updated", requestID) + return true, "" + default: + reportRuntimeLog("warning", "task", "task-manager", "unknown task type: "+taskType, requestID) + return true, "" + } +} diff --git a/EdgeHttpDNS/internal/rpc/rpc_client.go b/EdgeHttpDNS/internal/rpc/rpc_client.go new file mode 100644 index 0000000..52d76c1 --- /dev/null +++ b/EdgeHttpDNS/internal/rpc/rpc_client.go @@ -0,0 +1,222 @@ +package rpc + +import ( + "context" + "crypto/tls" + "encoding/base64" + "errors" + "fmt" + "net/url" + "sync" + "time" + + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeHttpDNS/internal/configs" + teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const" + "github.com/TeaOSLab/EdgeHttpDNS/internal/encrypt" + "github.com/iwind/TeaGo/maps" + "github.com/iwind/TeaGo/rands" + "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/encoding/gzip" + "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/metadata" + "sync/atomic" +) + + +type RPCClient struct { + apiConfig *configs.APIConfig + conns []*grpc.ClientConn + locker sync.RWMutex + + NodeTaskRPC pb.NodeTaskServiceClient + HTTPDNSNodeRPC pb.HTTPDNSNodeServiceClient + HTTPDNSClusterRPC pb.HTTPDNSClusterServiceClient + HTTPDNSAppRPC pb.HTTPDNSAppServiceClient + HTTPDNSDomainRPC pb.HTTPDNSDomainServiceClient + HTTPDNSRuleRPC pb.HTTPDNSRuleServiceClient + HTTPDNSRuntimeLogRPC pb.HTTPDNSRuntimeLogServiceClient + HTTPDNSAccessLogRPC pb.HTTPDNSAccessLogServiceClient + HTTPDNSSandboxRPC pb.HTTPDNSSandboxServiceClient + + totalRequests int64 + failedRequests int64 + totalCostMs int64 +} + + +func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) { + if apiConfig == nil { + return nil, errors.New("api config should not be nil") + } + + client := &RPCClient{apiConfig: apiConfig} + client.NodeTaskRPC = pb.NewNodeTaskServiceClient(client) + client.HTTPDNSNodeRPC = pb.NewHTTPDNSNodeServiceClient(client) + client.HTTPDNSClusterRPC = pb.NewHTTPDNSClusterServiceClient(client) + client.HTTPDNSAppRPC = pb.NewHTTPDNSAppServiceClient(client) + client.HTTPDNSDomainRPC = pb.NewHTTPDNSDomainServiceClient(client) + client.HTTPDNSRuleRPC = pb.NewHTTPDNSRuleServiceClient(client) + client.HTTPDNSRuntimeLogRPC = pb.NewHTTPDNSRuntimeLogServiceClient(client) + client.HTTPDNSAccessLogRPC = pb.NewHTTPDNSAccessLogServiceClient(client) + client.HTTPDNSSandboxRPC = pb.NewHTTPDNSSandboxServiceClient(client) + + err := client.init() + if err != nil { + return nil, err + } + return client, nil +} + +func (c *RPCClient) Context() context.Context { + ctx := context.Background() + payload := maps.Map{ + "timestamp": time.Now().Unix(), + "type": "httpdns", + "userId": 0, + } + + method, err := encrypt.NewMethodInstance(teaconst.EncryptMethod, c.apiConfig.Secret, c.apiConfig.NodeId) + if err != nil { + return context.Background() + } + encrypted, err := method.Encrypt(payload.AsJSON()) + if err != nil { + return context.Background() + } + + token := base64.StdEncoding.EncodeToString(encrypted) + return metadata.AppendToOutgoingContext(ctx, "nodeId", c.apiConfig.NodeId, "token", token) +} + +func (c *RPCClient) UpdateConfig(config *configs.APIConfig) error { + c.apiConfig = config + c.locker.Lock() + defer c.locker.Unlock() + return c.init() +} + +func (c *RPCClient) init() error { + conns := []*grpc.ClientConn{} + for _, endpoint := range c.apiConfig.RPCEndpoints { + u, err := url.Parse(endpoint) + if err != nil { + return fmt.Errorf("parse endpoint failed: %w", err) + } + + var conn *grpc.ClientConn + callOptions := grpc.WithDefaultCallOptions( + grpc.MaxCallRecvMsgSize(128<<20), + grpc.MaxCallSendMsgSize(128<<20), + grpc.UseCompressor(gzip.Name), + ) + keepaliveParams := grpc.WithKeepaliveParams(keepalive.ClientParameters{ + Time: 30 * time.Second, + }) + + if u.Scheme == "http" { + conn, err = grpc.Dial(u.Host, grpc.WithTransportCredentials(insecure.NewCredentials()), callOptions, keepaliveParams) + } else if u.Scheme == "https" { + conn, err = grpc.Dial(u.Host, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{ + InsecureSkipVerify: true, + })), callOptions, keepaliveParams) + } else { + return errors.New("invalid endpoint scheme '" + u.Scheme + "'") + } + if err != nil { + return err + } + conns = append(conns, conn) + } + + if len(conns) == 0 { + return errors.New("no available rpc endpoints") + } + + c.conns = conns + return nil +} + +func (c *RPCClient) pickConn() *grpc.ClientConn { + c.locker.RLock() + defer c.locker.RUnlock() + + countConns := len(c.conns) + if countConns == 0 { + return nil + } + if countConns == 1 { + return c.conns[0] + } + + for _, state := range []connectivity.State{ + connectivity.Ready, + connectivity.Idle, + connectivity.Connecting, + connectivity.TransientFailure, + } { + available := []*grpc.ClientConn{} + for _, conn := range c.conns { + if conn.GetState() == state { + available = append(available, conn) + } + } + if len(available) > 0 { + return c.randConn(available) + } + } + + return c.randConn(c.conns) +} + +func (c *RPCClient) randConn(conns []*grpc.ClientConn) *grpc.ClientConn { + l := len(conns) + if l == 0 { + return nil + } + if l == 1 { + return conns[0] + } + return conns[rands.Int(0, l-1)] +} + +func (c *RPCClient) Invoke(ctx context.Context, method string, args interface{}, reply interface{}, opts ...grpc.CallOption) error { + conn := c.pickConn() + if conn == nil { + return errors.New("can not get available grpc connection") + } + + atomic.AddInt64(&c.totalRequests, 1) + start := time.Now() + err := conn.Invoke(ctx, method, args, reply, opts...) + costMs := time.Since(start).Milliseconds() + atomic.AddInt64(&c.totalCostMs, costMs) + + if err != nil { + atomic.AddInt64(&c.failedRequests, 1) + } + return err +} + +func (c *RPCClient) GetAndResetMetrics() (total int64, failed int64, avgCostSeconds float64) { + total = atomic.SwapInt64(&c.totalRequests, 0) + failed = atomic.SwapInt64(&c.failedRequests, 0) + costMs := atomic.SwapInt64(&c.totalCostMs, 0) + + if total > 0 { + avgCostSeconds = float64(costMs) / float64(total) / 1000.0 + } + 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 { + return nil, errors.New("can not get available grpc connection") + } + return conn.NewStream(ctx, desc, method, opts...) +} diff --git a/EdgeHttpDNS/internal/rpc/shared.go b/EdgeHttpDNS/internal/rpc/shared.go new file mode 100644 index 0000000..bff809e --- /dev/null +++ b/EdgeHttpDNS/internal/rpc/shared.go @@ -0,0 +1,31 @@ +package rpc + +import ( + "sync" + + "github.com/TeaOSLab/EdgeHttpDNS/internal/configs" +) + +var sharedRPCClient *RPCClient +var sharedLocker sync.Mutex + +func SharedRPC() (*RPCClient, error) { + sharedLocker.Lock() + defer sharedLocker.Unlock() + + config, err := configs.SharedAPIConfig() + if err != nil { + return nil, err + } + + if sharedRPCClient == nil { + client, err := NewRPCClient(config) + if err != nil { + return nil, err + } + sharedRPCClient = client + return sharedRPCClient, nil + } + + return sharedRPCClient, nil +} diff --git a/EdgeHttpDNS/internal/utils/ip.go b/EdgeHttpDNS/internal/utils/ip.go new file mode 100644 index 0000000..88ea3c9 --- /dev/null +++ b/EdgeHttpDNS/internal/utils/ip.go @@ -0,0 +1,18 @@ +package utils + +import ( + "encoding/binary" + "net" +) + +func IP2Long(ip string) uint32 { + s := net.ParseIP(ip) + if s == nil { + return 0 + } + + if len(s) == 16 { + return binary.BigEndian.Uint32(s[12:16]) + } + return binary.BigEndian.Uint32(s) +} diff --git a/EdgeHttpDNS/internal/utils/service.go b/EdgeHttpDNS/internal/utils/service.go new file mode 100644 index 0000000..2435036 --- /dev/null +++ b/EdgeHttpDNS/internal/utils/service.go @@ -0,0 +1,46 @@ +package utils + +import ( + "os" + "path/filepath" + "sync" + + "github.com/iwind/TeaGo/Tea" +) + +type ServiceManager struct { + Name string + Description string + + onceLocker sync.Once +} + +func NewServiceManager(name, description string) *ServiceManager { + manager := &ServiceManager{ + Name: name, + Description: description, + } + manager.resetRoot() + return manager +} + +func (m *ServiceManager) setup() { + m.onceLocker.Do(func() {}) +} + +func (m *ServiceManager) resetRoot() { + if !Tea.IsTesting() { + exePath, err := os.Executable() + if err != nil { + exePath = os.Args[0] + } + link, err := filepath.EvalSymlinks(exePath) + if err == nil { + exePath = link + } + fullPath, err := filepath.Abs(exePath) + if err == nil { + Tea.UpdateRoot(filepath.Dir(filepath.Dir(fullPath))) + } + } +} diff --git a/EdgeHttpDNS/internal/utils/service_linux.go b/EdgeHttpDNS/internal/utils/service_linux.go new file mode 100644 index 0000000..3b08e92 --- /dev/null +++ b/EdgeHttpDNS/internal/utils/service_linux.go @@ -0,0 +1,65 @@ +//go:build linux +// +build linux + +package utils + +import ( + "errors" + "os" + "os/exec" + + teaconst "github.com/TeaOSLab/EdgeHttpDNS/internal/const" +) + +var systemdServiceFile = "/etc/systemd/system/" + teaconst.SystemdServiceName + ".service" + +func (m *ServiceManager) Install(exePath string, args []string) error { + if os.Getgid() != 0 { + return errors.New("only root users can install the service") + } + + systemd, err := exec.LookPath("systemctl") + if err != nil { + return err + } + + desc := `[Unit] +Description=GoEdge HTTPDNS Node Service +Before=shutdown.target +After=network-online.target + +[Service] +Type=simple +Restart=always +RestartSec=1s +ExecStart=` + exePath + ` daemon +ExecStop=` + exePath + ` stop +ExecReload=` + exePath + ` restart + +[Install] +WantedBy=multi-user.target` + + err = os.WriteFile(systemdServiceFile, []byte(desc), 0777) + if err != nil { + return err + } + + _ = exec.Command(systemd, "stop", teaconst.SystemdServiceName+".service").Run() + _ = exec.Command(systemd, "daemon-reload").Run() + return exec.Command(systemd, "enable", teaconst.SystemdServiceName+".service").Run() +} + +func (m *ServiceManager) Uninstall() error { + if os.Getgid() != 0 { + return errors.New("only root users can uninstall the service") + } + + systemd, err := exec.LookPath("systemctl") + if err != nil { + return err + } + + _ = exec.Command(systemd, "disable", teaconst.SystemdServiceName+".service").Run() + _ = exec.Command(systemd, "daemon-reload").Run() + return os.Remove(systemdServiceFile) +} diff --git a/EdgeHttpDNS/internal/utils/service_others.go b/EdgeHttpDNS/internal/utils/service_others.go new file mode 100644 index 0000000..e42b43c --- /dev/null +++ b/EdgeHttpDNS/internal/utils/service_others.go @@ -0,0 +1,14 @@ +//go:build !linux +// +build !linux + +package utils + +import "errors" + +func (m *ServiceManager) Install(exePath string, args []string) error { + return errors.New("service install is only supported on linux in this version") +} + +func (m *ServiceManager) Uninstall() error { + return errors.New("service uninstall is only supported on linux in this version") +} diff --git a/EdgeHttpDNS/internal/utils/version.go b/EdgeHttpDNS/internal/utils/version.go new file mode 100644 index 0000000..0e28897 --- /dev/null +++ b/EdgeHttpDNS/internal/utils/version.go @@ -0,0 +1,15 @@ +package utils + +import "strings" + +func VersionToLong(version string) uint32 { + countDots := strings.Count(version, ".") + if countDots == 2 { + version += ".0" + } else if countDots == 1 { + version += ".0.0" + } else if countDots == 0 { + version += ".0.0.0" + } + return IP2Long(version) +} diff --git a/EdgeHttpDNS/sdk/android/README.md b/EdgeHttpDNS/sdk/android/README.md index 1b74dd9..ce9312b 100644 --- a/EdgeHttpDNS/sdk/android/README.md +++ b/EdgeHttpDNS/sdk/android/README.md @@ -1,148 +1,77 @@ -# Alicloud HTTPDNS Android SDK +# HTTPDNS Android SDK (SNI Hidden v1.0.0) -面向 Android 的 HTTP/HTTPS DNS 解析 SDK,提供鉴权与可选 AES 加密、IPv4/IPv6 双栈解析、缓存与调度、预解析等能力。最低支持 Android API 19(Android 4.4)。 - -## 功能特性 - -- 鉴权请求与可选 AES 传输加密 -- IPv4/IPv6 双栈解析,支持自动/同时解析 -- 内存 + 持久化缓存与 TTL 控制,可选择复用过期 IP -- 预解析、区域路由、网络切换自动刷新 -- 可定制日志回调与会话追踪 `sessionId` - -## 安装(Gradle) - -在项目的 `build.gradle` 中添加: - -```groovy -dependencies { - implementation 'com.aliyun.ams:alicloud-android-httpdns:2.6.7' -} -``` - -请访问 [Android SDK发布说明](https://help.aliyun.com/document_detail/435251.html) 查看最新版本号。 - -## 快速开始 - -### Java +## 1. Init ```java import com.alibaba.sdk.android.httpdns.HttpDns; import com.alibaba.sdk.android.httpdns.HttpDnsService; import com.alibaba.sdk.android.httpdns.InitConfig; -import com.alibaba.sdk.android.httpdns.RequestIpType; -// 初始化配置 +String appId = "app1f1ndpo9"; + new InitConfig.Builder() .setContext(context) - .setSecretKey("YOUR_SECRET_KEY") - .setEnableExpiredIp(true) // 允许返回过期 IP - .buildFor("YOUR_ACCOUNT_ID"); + .setPrimaryServiceHost("httpdns-a.example.com") + .setBackupServiceHost("httpdns-b.example.com") + .setServicePort(443) + .setSecretKey("your-sign-secret") // optional if sign is enabled + .setEnableHttps(true) + .buildFor(appId); -// 获取实例 -HttpDnsService httpDns = HttpDns.getService("YOUR_ACCOUNT_ID"); - -// 预解析热点域名 -httpDns.setPreResolveHosts(new ArrayList<>(Arrays.asList("www.aliyun.com"))); - -// 解析域名 -HTTPDNSResult result = httpDns.getHttpDnsResultForHostSyncNonBlocking("www.aliyun.com", RequestIpType.auto); -String[] ips = result.getIps(); +HttpDnsService httpDnsService = HttpDns.getService(appId); ``` -### Kotlin - -```kotlin -import com.alibaba.sdk.android.httpdns.HttpDns -import com.alibaba.sdk.android.httpdns.InitConfig -import com.alibaba.sdk.android.httpdns.RequestIpType - -// 初始化配置 -InitConfig.Builder() - .setContext(context) - .setSecretKey("YOUR_SECRET_KEY") - .setEnableExpiredIp(true) // 允许返回过期 IP - .buildFor("YOUR_ACCOUNT_ID") - -// 获取实例 -val httpDns = HttpDns.getService("YOUR_ACCOUNT_ID") - -// 预解析热点域名 -httpDns.setPreResolveHosts(arrayListOf("www.aliyun.com")) - -// 解析域名 -val result = httpDns.getHttpDnsResultForHostSyncNonBlocking("www.aliyun.com", RequestIpType.auto) -val ips = result.ips -``` - -### 提示 - -- 启动时通过 `setPreResolveHosts()` 预热热点域名 -- 如需在刷新期间容忍 TTL 过期,可开启 `setEnableExpiredIp(true)` -- 使用 `getSessionId()` 并与选用 IP 一同记录,便于排障 - -## 源码构建 - -```bash -./gradlew clean :httpdns-sdk:assembleRelease -``` - -构建产物位于 `httpdns-sdk/build/outputs/aar/` 目录。 - -### 版本说明 - -项目使用 `productFlavors` 区分不同版本: -- `normal`:中国大陆版本 -- `intl`:国际版本 -- `end2end`:用于单元测试 - -## 测试 - -### 运行单元测试 - -```bash -./gradlew clean :httpdns-sdk:testEnd2endForTestUnitTest -``` - -### Demo 应用 - -SDK 提供了两个 Demo: - -#### 1. app module(旧版 Demo) - -在 `MyApp.java` 中配置测试账号: +## 2. Resolve ```java -private HttpDnsHolder holderA = new HttpDnsHolder("请替换为测试用A实例的accountId", "请替换为测试用A实例的secret"); -private HttpDnsHolder holderB = new HttpDnsHolder("请替换为测试用B实例的accountId", null); +HTTPDNSResult result = httpDnsService.getHttpDnsResultForHostSyncNonBlocking( + "api.business.com", + RequestIpType.auto, + null, + null +); ``` -> 两个实例用于测试实例间互不影响,体验时只需配置一个 +## 3. Official HTTP Adapter (IP + Empty-SNI + Host) -#### 2. demo module(推荐) +```java +import com.alibaba.sdk.android.httpdns.network.HttpDnsAdapterOptions; +import com.alibaba.sdk.android.httpdns.network.HttpDnsAdapterRequest; +import com.alibaba.sdk.android.httpdns.network.HttpDnsAdapterResponse; +import com.alibaba.sdk.android.httpdns.network.HttpDnsHttpAdapter; -使用 Kotlin + MVVM 开发,功能更丰富。在 `demo/build.gradle` 中配置测试账号: +HttpDnsHttpAdapter adapter = HttpDns.buildHttpClientAdapter( + httpDnsService, + new HttpDnsAdapterOptions.Builder() + .setConnectTimeoutMillis(3000) + .setReadTimeoutMillis(5000) + .setRequestIpType(RequestIpType.auto) + .setAllowInsecureCertificatesForDebugOnly(false) + .build() +); -```groovy -buildConfigField "String", "ACCOUNT_ID", "\"请替换为测试用实例的accountId\"" -buildConfigField "String", "SECRET_KEY", "\"请替换为测试用实例的secret\"" -buildConfigField "String", "AES_SECRET_KEY", "\"请替换为测试用实例的aes\"" +HttpDnsAdapterResponse response = adapter.execute( + new HttpDnsAdapterRequest("GET", "https://api.business.com/v1/ping") +); ``` -## 依赖与要求 +Behavior is fixed: +- Resolve by `/resolve`. +- Connect to resolved IP over HTTPS. +- Keep `Host` header as business domain. +- No fallback to domain direct request. -- Android API 19+(Android 4.4+) -- 需要权限:`INTERNET`、`ACCESS_NETWORK_STATE` +## 4. Public Errors -## 安全说明 +- `NO_IP_AVAILABLE` +- `TLS_EMPTY_SNI_FAILED` +- `HOST_ROUTE_REJECTED` +- `RESOLVE_SIGN_INVALID` -- 切勿提交真实的 AccountID/SecretKey,请通过本地安全配置或 CI 注入 -- 若担心设备时间偏差影响鉴权,可使用 `setAuthCurrentTime()` 校正时间 +## 5. Removed Public Params -## 文档 - -官方文档:[Android SDK手册](https://help.aliyun.com/document_detail/435250.html) - -## 感谢 - -本项目中 Inet64Util 工具类由 [Shinelw](https://github.com/Shinelw) 贡献支持,感谢。 +Do not use legacy public parameters: +- `accountId` +- `serviceDomain` +- `endpoint` +- `aesSecretKey` diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/end2end/java/com/alibaba/sdk/android/httpdns/HttpDns.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/end2end/java/com/alibaba/sdk/android/httpdns/HttpDns.java index 38b3fcb..29a5c08 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/end2end/java/com/alibaba/sdk/android/httpdns/HttpDns.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/end2end/java/com/alibaba/sdk/android/httpdns/HttpDns.java @@ -5,6 +5,8 @@ import android.content.Context; import com.alibaba.sdk.android.httpdns.impl.HttpDnsInstanceHolder; import com.alibaba.sdk.android.httpdns.impl.InstanceCreator; import com.alibaba.sdk.android.httpdns.net.NetworkStateManager; +import com.alibaba.sdk.android.httpdns.network.HttpDnsAdapterOptions; +import com.alibaba.sdk.android.httpdns.network.HttpDnsHttpAdapter; import com.alibaba.sdk.android.httpdns.utils.CommonUtil; /** @@ -66,4 +68,18 @@ public class HttpDns { sHolder = new HttpDnsInstanceHolder(new InstanceCreator()); NetworkStateManager.getInstance().reset(); } + + /** + * Build official IP-direct + empty-SNI adapter. + */ + public static HttpDnsHttpAdapter buildHttpClientAdapter(HttpDnsService service) { + return new HttpDnsHttpAdapter(service); + } + + /** + * Build official IP-direct + empty-SNI adapter with options. + */ + public static HttpDnsHttpAdapter buildHttpClientAdapter(HttpDnsService service, HttpDnsAdapterOptions options) { + return new HttpDnsHttpAdapter(service, options); + } } diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/intl/java/com/alibaba/sdk/android/httpdns/HttpDns.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/intl/java/com/alibaba/sdk/android/httpdns/HttpDns.java index 316ddc3..578f286 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/intl/java/com/alibaba/sdk/android/httpdns/HttpDns.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/intl/java/com/alibaba/sdk/android/httpdns/HttpDns.java @@ -2,6 +2,8 @@ package com.alibaba.sdk.android.httpdns; import com.alibaba.sdk.android.httpdns.impl.HttpDnsInstanceHolder; import com.alibaba.sdk.android.httpdns.impl.InstanceCreator; +import com.alibaba.sdk.android.httpdns.network.HttpDnsAdapterOptions; +import com.alibaba.sdk.android.httpdns.network.HttpDnsHttpAdapter; import com.alibaba.sdk.android.httpdns.utils.CommonUtil; import android.content.Context; @@ -73,6 +75,20 @@ public class HttpDns { InitConfig.addConfig(accountId, config); } + /** + * Build official IP-direct + empty-SNI adapter. + */ + public static HttpDnsHttpAdapter buildHttpClientAdapter(HttpDnsService service) { + return new HttpDnsHttpAdapter(service); + } + + /** + * Build official IP-direct + empty-SNI adapter with options. + */ + public static HttpDnsHttpAdapter buildHttpClientAdapter(HttpDnsService service, HttpDnsAdapterOptions options) { + return new HttpDnsHttpAdapter(service, options); + } + /** * 启用或者禁用httpdns,理论上这个是内部接口,不给外部使用的 * 但是已经对外暴露,所以保留 diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/HttpDnsV1Client.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/HttpDnsV1Client.java new file mode 100644 index 0000000..5b47c07 --- /dev/null +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/HttpDnsV1Client.java @@ -0,0 +1,71 @@ +package com.alibaba.sdk.android.httpdns; + +import android.content.Context; +import android.text.TextUtils; + +import com.alibaba.sdk.android.httpdns.network.HttpDnsAdapterOptions; +import com.alibaba.sdk.android.httpdns.network.HttpDnsHttpAdapter; + +import java.util.HashMap; +import java.util.Map; + +public final class HttpDnsV1Client { + private HttpDnsV1Client() { + } + + public static HttpDnsService init(Context context, + String appId, + String primaryServiceHost, + String backupServiceHost, + int servicePort, + String signSecret) { + InitConfig.Builder builder = new InitConfig.Builder() + .setContext(context) + .setEnableHttps(true) + .setPrimaryServiceHost(primaryServiceHost) + .setServicePort(servicePort > 0 ? servicePort : 443); + + if (!TextUtils.isEmpty(backupServiceHost)) { + builder.setBackupServiceHost(backupServiceHost); + } + if (!TextUtils.isEmpty(signSecret)) { + builder.setSecretKey(signSecret); + } + + builder.buildFor(appId); + if (!TextUtils.isEmpty(signSecret)) { + return HttpDns.getService(context, appId, signSecret); + } + return HttpDns.getService(context, appId); + } + + public static HTTPDNSResult resolveHost(HttpDnsService service, + String host, + String qtype, + String cip) { + if (service == null) { + return HTTPDNSResult.empty(host); + } + RequestIpType requestIpType = RequestIpType.auto; + if ("AAAA".equalsIgnoreCase(qtype)) { + requestIpType = RequestIpType.v6; + } + + Map params = null; + if (!TextUtils.isEmpty(cip)) { + params = new HashMap<>(); + params.put("cip", cip); + } + + return service.getHttpDnsResultForHostSyncNonBlocking(host, requestIpType, params, host); + } + + public static HttpDnsHttpAdapter buildHttpClientAdapter(HttpDnsService service) { + return HttpDns.buildHttpClientAdapter(service); + } + + public static HttpDnsHttpAdapter buildHttpClientAdapter(HttpDnsService service, + HttpDnsAdapterOptions options) { + return HttpDns.buildHttpClientAdapter(service, options); + } +} diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/InitConfig.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/InitConfig.java index 81e5ae3..3dea324 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/InitConfig.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/InitConfig.java @@ -61,6 +61,9 @@ public class InitConfig { private final String mBizTags; private final String aesSecretKey; private final String secretKey; + private final String primaryServiceHost; + private final String backupServiceHost; + private final int servicePort; private final Context context; private InitConfig(Builder builder) { @@ -82,6 +85,9 @@ public class InitConfig { mEnableObservable = builder.enableObservable; mBizTags = builder.bizTags; aesSecretKey = builder.aesSecretKey; + primaryServiceHost = builder.primaryServiceHost; + backupServiceHost = builder.backupServiceHost; + servicePort = builder.servicePort; context = builder.context; secretKey = builder.secretKey; } @@ -159,6 +165,18 @@ public class InitConfig { return aesSecretKey; } + public String getPrimaryServiceHost() { + return primaryServiceHost; + } + + public String getBackupServiceHost() { + return backupServiceHost; + } + + public int getServicePort() { + return servicePort; + } + public Context getContext() {return context;} public String getSecretKey() { @@ -184,6 +202,9 @@ public class InitConfig { private Map sdnsGlobalParams = null; private String bizTags = null; private String aesSecretKey = null; + private String primaryServiceHost = null; + private String backupServiceHost = null; + private int servicePort = -1; private Context context = null; private String secretKey = null; @@ -415,6 +436,43 @@ public class InitConfig { return this; } + /** + * 设置主服务域名。 + */ + public Builder setPrimaryServiceHost(String host) { + this.primaryServiceHost = host; + return this; + } + + /** + * 设置备服务域名。 + */ + public Builder setBackupServiceHost(String host) { + this.backupServiceHost = host; + return this; + } + + /** + * 批量设置服务域名,支持主备两个。 + */ + public Builder setServiceHosts(List hosts) { + if (hosts != null && hosts.size() > 0) { + this.primaryServiceHost = hosts.get(0); + } + if (hosts != null && hosts.size() > 1) { + this.backupServiceHost = hosts.get(1); + } + return this; + } + + /** + * 设置服务端口,默认 -1 表示使用协议默认端口。 + */ + public Builder setServicePort(int port) { + this.servicePort = port; + return this; + } + /** * 设置context * @param context 上下文 diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/impl/HttpDnsServiceImpl.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/impl/HttpDnsServiceImpl.java index f24e462..efc05ec 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/impl/HttpDnsServiceImpl.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/impl/HttpDnsServiceImpl.java @@ -1,6 +1,7 @@ package com.alibaba.sdk.android.httpdns.impl; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -41,6 +42,7 @@ import com.alibaba.sdk.android.httpdns.utils.Constants; import android.content.Context; import android.content.SharedPreferences; import android.os.Looper; +import android.text.TextUtils; /** * 域名解析服务 httpdns接口的实现 @@ -60,6 +62,7 @@ public class HttpDnsServiceImpl implements HttpDnsService, OnRegionServerIpUpdat private SignService mSignService; private AESEncryptService mAESEncryptService; private boolean resolveAfterNetworkChange = true; + private boolean mUseCustomServiceHosts = false; /** * crash defend 默认关闭 */ @@ -115,7 +118,9 @@ public class HttpDnsServiceImpl implements HttpDnsService, OnRegionServerIpUpdat tryUpdateRegionServer(sContext, accountId); - mRegionServerRankingService.rankServiceIp(mHttpDnsConfig.getCurrentServer()); + if (!mUseCustomServiceHosts) { + mRegionServerRankingService.rankServiceIp(mHttpDnsConfig.getCurrentServer()); + } favorInit(sContext, accountId); if (HttpDnsLog.isPrint()) { @@ -163,10 +168,37 @@ public class HttpDnsServiceImpl implements HttpDnsService, OnRegionServerIpUpdat mRequestHandler.setSdnsGlobalParams(config.getSdnsGlobalParams()); mAESEncryptService.setAesSecretKey(config.getAesSecretKey()); + applyCustomServiceHosts(config); } } + private void applyCustomServiceHosts(InitConfig config) { + String primaryHost = config.getPrimaryServiceHost(); + String backupHost = config.getBackupServiceHost(); + ArrayList hosts = new ArrayList<>(); + if (!TextUtils.isEmpty(primaryHost)) { + hosts.add(primaryHost.trim()); + } + if (!TextUtils.isEmpty(backupHost) && !backupHost.trim().equalsIgnoreCase(primaryHost == null ? "" : primaryHost.trim())) { + hosts.add(backupHost.trim()); + } + if (hosts.isEmpty()) { + return; + } + + String[] serverHosts = hosts.toArray(new String[0]); + int[] ports = new int[serverHosts.length]; + int servicePort = config.getServicePort(); + Arrays.fill(ports, servicePort > 0 ? servicePort : -1); + + mHttpDnsConfig.setInitServers(mHttpDnsConfig.getRegion(), serverHosts, ports, serverHosts, ports); + mHttpDnsConfig.setDefaultUpdateServer(serverHosts, ports); + mHttpDnsConfig.setDefaultUpdateServerIpv6(serverHosts, ports); + mHttpDnsConfig.setHTTPSRequestEnabled(true); + mUseCustomServiceHosts = true; + } + protected void beforeInit() { // only for test } @@ -218,7 +250,9 @@ public class HttpDnsServiceImpl implements HttpDnsService, OnRegionServerIpUpdat mRequestHandler.resetStatus(); //服务IP更新,触发服务IP测速 - mRegionServerRankingService.rankServiceIp(mHttpDnsConfig.getCurrentServer()); + if (!mUseCustomServiceHosts) { + mRegionServerRankingService.rankServiceIp(mHttpDnsConfig.getCurrentServer()); + } } @Override @@ -589,6 +623,12 @@ public class HttpDnsServiceImpl implements HttpDnsService, OnRegionServerIpUpdat @Override public void setRegion(String region) { + if (mUseCustomServiceHosts) { + if (HttpDnsLog.isPrint()) { + HttpDnsLog.d("ignore setRegion in custom service host mode"); + } + return; + } if (!mHttpDnsConfig.isEnabled()) { HttpDnsLog.i("service is disabled"); return; @@ -605,9 +645,13 @@ public class HttpDnsServiceImpl implements HttpDnsService, OnRegionServerIpUpdat if (changed) { mResultRepo.clearMemoryCache(); //region变化,服务IP变成对应的预置IP,触发测速 - mRegionServerRankingService.rankServiceIp(mHttpDnsConfig.getCurrentServer()); + if (!mUseCustomServiceHosts) { + mRegionServerRankingService.rankServiceIp(mHttpDnsConfig.getCurrentServer()); + } + } + if (!mUseCustomServiceHosts) { + mScheduleService.updateRegionServerIps(region, Constants.UPDATE_REGION_SERVER_SCENES_REGION_CHANGE); } - mScheduleService.updateRegionServerIps(region, Constants.UPDATE_REGION_SERVER_SCENES_REGION_CHANGE); } @Override @@ -684,7 +728,9 @@ public class HttpDnsServiceImpl implements HttpDnsService, OnRegionServerIpUpdat }); //网络变化,触发服务IP测速 - mRegionServerRankingService.rankServiceIp(mHttpDnsConfig.getCurrentServer()); + if (!mUseCustomServiceHosts) { + mRegionServerRankingService.rankServiceIp(mHttpDnsConfig.getCurrentServer()); + } } catch (Exception e) { } } @@ -817,6 +863,9 @@ public class HttpDnsServiceImpl implements HttpDnsService, OnRegionServerIpUpdat } private void tryUpdateRegionServer(Context context, String accountId) { + if (mUseCustomServiceHosts) { + return; + } if (mHttpDnsConfig.getCurrentServer().shouldUpdateServerIp()) { mScheduleService.updateRegionServerIps(Constants.UPDATE_REGION_SERVER_SCENES_INIT); diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/impl/SignService.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/impl/SignService.java index 65905ab..de61652 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/impl/SignService.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/impl/SignService.java @@ -3,7 +3,6 @@ package com.alibaba.sdk.android.httpdns.impl; import android.text.TextUtils; import com.alibaba.sdk.android.httpdns.log.HttpDnsLog; -import com.alibaba.sdk.android.httpdns.utils.CommonUtil; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; @@ -67,6 +66,30 @@ public class SignService { return signStr; } + /** + * 新版 /resolve 请求签名: + * appId|lower(domain)|upper(qtype)|exp|nonce + */ + public String signResolve(String appId, String domain, String qtype, String exp, String nonce) { + if (TextUtils.isEmpty(mSecretKey) + || TextUtils.isEmpty(appId) + || TextUtils.isEmpty(domain) + || TextUtils.isEmpty(qtype) + || TextUtils.isEmpty(exp) + || TextUtils.isEmpty(nonce)) { + return ""; + } + String raw = appId + "|" + domain.toLowerCase() + "|" + qtype.toUpperCase() + "|" + exp + "|" + nonce; + try { + return hmacSha256(raw); + } catch (Exception e) { + if (HttpDnsLog.isPrint()) { + HttpDnsLog.e("sign resolve fail.", e); + } + return ""; + } + } + private static String generateV2SignContent(Map map) { Map sortedMap = new TreeMap<>(); for(Map.Entry entry : map.entrySet()) { @@ -91,9 +114,17 @@ public class SignService { private String hmacSha256(String content) throws NoSuchAlgorithmException, InvalidKeyException { Mac mac = Mac.getInstance(ALGORITHM); - mac.init(new SecretKeySpec(CommonUtil.decodeHex(mSecretKey), ALGORITHM)); + mac.init(new SecretKeySpec(mSecretKey.getBytes(StandardCharsets.UTF_8), ALGORITHM)); byte[] signedBytes = mac.doFinal(content.getBytes(StandardCharsets.UTF_8)); - return CommonUtil.encodeHexString(signedBytes); + StringBuilder sb = new StringBuilder(signedBytes.length * 2); + for (byte b : signedBytes) { + String h = Integer.toHexString(b & 0xff); + if (h.length() == 1) { + sb.append('0'); + } + sb.append(h); + } + return sb.toString(); } public void setCurrentTimestamp(long serverTime) { diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterException.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterException.java new file mode 100644 index 0000000..21312c7 --- /dev/null +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterException.java @@ -0,0 +1,21 @@ +package com.alibaba.sdk.android.httpdns.network; + +import java.io.IOException; + +public class HttpDnsAdapterException extends IOException { + private final String errorCode; + + public HttpDnsAdapterException(String errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + + public HttpDnsAdapterException(String errorCode, String message, Throwable cause) { + super(message, cause); + this.errorCode = errorCode; + } + + public String getErrorCode() { + return errorCode; + } +} diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterOptions.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterOptions.java new file mode 100644 index 0000000..61d321b --- /dev/null +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterOptions.java @@ -0,0 +1,70 @@ +package com.alibaba.sdk.android.httpdns.network; + +import com.alibaba.sdk.android.httpdns.RequestIpType; + +public class HttpDnsAdapterOptions { + private final int connectTimeoutMillis; + private final int readTimeoutMillis; + private final boolean allowInsecureCertificatesForDebugOnly; + private final RequestIpType requestIpType; + + private HttpDnsAdapterOptions(Builder builder) { + connectTimeoutMillis = builder.connectTimeoutMillis; + readTimeoutMillis = builder.readTimeoutMillis; + allowInsecureCertificatesForDebugOnly = builder.allowInsecureCertificatesForDebugOnly; + requestIpType = builder.requestIpType; + } + + public int getConnectTimeoutMillis() { + return connectTimeoutMillis; + } + + public int getReadTimeoutMillis() { + return readTimeoutMillis; + } + + public boolean isAllowInsecureCertificatesForDebugOnly() { + return allowInsecureCertificatesForDebugOnly; + } + + public RequestIpType getRequestIpType() { + return requestIpType; + } + + public static class Builder { + private int connectTimeoutMillis = 3000; + private int readTimeoutMillis = 5000; + private boolean allowInsecureCertificatesForDebugOnly = false; + private RequestIpType requestIpType = RequestIpType.auto; + + public Builder setConnectTimeoutMillis(int value) { + if (value > 0) { + connectTimeoutMillis = value; + } + return this; + } + + public Builder setReadTimeoutMillis(int value) { + if (value > 0) { + readTimeoutMillis = value; + } + return this; + } + + public Builder setAllowInsecureCertificatesForDebugOnly(boolean value) { + allowInsecureCertificatesForDebugOnly = value; + return this; + } + + public Builder setRequestIpType(RequestIpType type) { + if (type != null) { + requestIpType = type; + } + return this; + } + + public HttpDnsAdapterOptions build() { + return new HttpDnsAdapterOptions(this); + } + } +} diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterRequest.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterRequest.java new file mode 100644 index 0000000..4bc7439 --- /dev/null +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterRequest.java @@ -0,0 +1,43 @@ +package com.alibaba.sdk.android.httpdns.network; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +public class HttpDnsAdapterRequest { + private final String method; + private final String url; + private final Map headers; + private final byte[] body; + + public HttpDnsAdapterRequest(String method, String url) { + this(method, url, null, null); + } + + public HttpDnsAdapterRequest(String method, String url, Map headers, byte[] body) { + this.method = method == null || method.trim().isEmpty() ? "GET" : method.trim().toUpperCase(); + this.url = url; + if (headers == null || headers.isEmpty()) { + this.headers = Collections.emptyMap(); + } else { + this.headers = Collections.unmodifiableMap(new LinkedHashMap<>(headers)); + } + this.body = body; + } + + public String getMethod() { + return method; + } + + public String getUrl() { + return url; + } + + public Map getHeaders() { + return headers; + } + + public byte[] getBody() { + return body; + } +} diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterResponse.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterResponse.java new file mode 100644 index 0000000..580c9a8 --- /dev/null +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsAdapterResponse.java @@ -0,0 +1,34 @@ +package com.alibaba.sdk.android.httpdns.network; + +import java.util.List; +import java.util.Map; + +public class HttpDnsAdapterResponse { + private final int statusCode; + private final Map> headers; + private final byte[] body; + private final String usedIp; + + public HttpDnsAdapterResponse(int statusCode, Map> headers, byte[] body, String usedIp) { + this.statusCode = statusCode; + this.headers = headers; + this.body = body; + this.usedIp = usedIp; + } + + public int getStatusCode() { + return statusCode; + } + + public Map> getHeaders() { + return headers; + } + + public byte[] getBody() { + return body; + } + + public String getUsedIp() { + return usedIp; + } +} diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsErrorCode.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsErrorCode.java new file mode 100644 index 0000000..bb3aaaf --- /dev/null +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsErrorCode.java @@ -0,0 +1,11 @@ +package com.alibaba.sdk.android.httpdns.network; + +public final class HttpDnsErrorCode { + private HttpDnsErrorCode() { + } + + public static final String NO_IP_AVAILABLE = "NO_IP_AVAILABLE"; + public static final String TLS_EMPTY_SNI_FAILED = "TLS_EMPTY_SNI_FAILED"; + public static final String HOST_ROUTE_REJECTED = "HOST_ROUTE_REJECTED"; + public static final String RESOLVE_SIGN_INVALID = "RESOLVE_SIGN_INVALID"; +} diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsHttpAdapter.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsHttpAdapter.java new file mode 100644 index 0000000..9ff994f --- /dev/null +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/network/HttpDnsHttpAdapter.java @@ -0,0 +1,308 @@ +package com.alibaba.sdk.android.httpdns.network; + +import com.alibaba.sdk.android.httpdns.HTTPDNSResult; +import com.alibaba.sdk.android.httpdns.HttpDnsService; +import com.alibaba.sdk.android.httpdns.RequestIpType; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +public class HttpDnsHttpAdapter { + private static final int BUFFER_SIZE = 4096; + + private final HttpDnsService httpDnsService; + private final HttpDnsAdapterOptions options; + + public HttpDnsHttpAdapter(HttpDnsService httpDnsService) { + this(httpDnsService, new HttpDnsAdapterOptions.Builder().build()); + } + + public HttpDnsHttpAdapter(HttpDnsService httpDnsService, HttpDnsAdapterOptions options) { + if (httpDnsService == null) { + throw new IllegalArgumentException("httpDnsService should not be null"); + } + this.httpDnsService = httpDnsService; + this.options = options == null ? new HttpDnsAdapterOptions.Builder().build() : options; + } + + public HttpDnsAdapterResponse execute(HttpDnsAdapterRequest request) throws IOException { + if (request == null || request.getUrl() == null || request.getUrl().trim().isEmpty()) { + throw new HttpDnsAdapterException(HttpDnsErrorCode.HOST_ROUTE_REJECTED, + "request or url is empty"); + } + + URL originalURL = new URL(request.getUrl()); + String originalHost = originalURL.getHost(); + if (originalHost == null || originalHost.trim().isEmpty()) { + throw new HttpDnsAdapterException(HttpDnsErrorCode.HOST_ROUTE_REJECTED, + "invalid original host"); + } + if (!"https".equalsIgnoreCase(originalURL.getProtocol())) { + throw new HttpDnsAdapterException(HttpDnsErrorCode.TLS_EMPTY_SNI_FAILED, + "only https scheme is supported in empty sni mode"); + } + + List candidateIps = resolveIps(originalHost); + if (candidateIps.isEmpty()) { + throw new HttpDnsAdapterException(HttpDnsErrorCode.NO_IP_AVAILABLE, + "HTTPDNS returned no ip for host: " + originalHost); + } + + IOException lastException = null; + for (String ip : candidateIps) { + if (ip == null || ip.trim().isEmpty()) { + continue; + } + String usedIp = ip.trim(); + HttpsURLConnection connection = null; + try { + int port = originalURL.getPort() > 0 ? originalURL.getPort() : 443; + URL targetURL = new URL("https", usedIp, port, originalURL.getFile()); + connection = (HttpsURLConnection) targetURL.openConnection(); + connection.setConnectTimeout(options.getConnectTimeoutMillis()); + connection.setReadTimeout(options.getReadTimeoutMillis()); + connection.setInstanceFollowRedirects(false); + connection.setRequestMethod(request.getMethod()); + connection.setSSLSocketFactory(createSocketFactory()); + connection.setHostnameVerifier(createHostnameVerifier(originalHost)); + connection.setRequestProperty("Host", originalHost); + for (Map.Entry entry : request.getHeaders().entrySet()) { + if (entry.getKey() == null || entry.getValue() == null) { + continue; + } + if ("host".equalsIgnoreCase(entry.getKey())) { + continue; + } + connection.setRequestProperty(entry.getKey(), entry.getValue()); + } + + byte[] body = request.getBody(); + if (body != null && body.length > 0 && allowsRequestBody(request.getMethod())) { + connection.setDoOutput(true); + connection.getOutputStream().write(body); + } + + int code = connection.getResponseCode(); + byte[] payload = readResponseBytes(connection, code); + Map> headers = sanitizeHeaders(connection.getHeaderFields()); + return new HttpDnsAdapterResponse(code, headers, payload, usedIp); + } catch (IOException e) { + lastException = e; + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } + + if (lastException == null) { + throw new HttpDnsAdapterException(HttpDnsErrorCode.TLS_EMPTY_SNI_FAILED, + "all ip attempts failed with no explicit exception"); + } + + throw new HttpDnsAdapterException(HttpDnsErrorCode.TLS_EMPTY_SNI_FAILED, + "all ip attempts failed", lastException); + } + + private List resolveIps(String host) { + RequestIpType type = options.getRequestIpType(); + HTTPDNSResult result = httpDnsService.getHttpDnsResultForHostSyncNonBlocking(host, type, null, null); + if (result == null) { + return Collections.emptyList(); + } + + List ips = new ArrayList<>(); + String[] v4 = result.getIps(); + if (v4 != null) { + for (String item : v4) { + if (item != null && item.length() > 0) { + ips.add(item); + } + } + } + String[] v6 = result.getIpv6s(); + if (v6 != null) { + for (String item : v6) { + if (item != null && item.length() > 0) { + ips.add(item); + } + } + } + return ips; + } + + private byte[] readResponseBytes(HttpsURLConnection connection, int code) throws IOException { + InputStream stream = code >= 400 ? connection.getErrorStream() : connection.getInputStream(); + if (stream == null) { + return new byte[0]; + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[BUFFER_SIZE]; + int count; + while ((count = stream.read(buffer)) > 0) { + out.write(buffer, 0, count); + } + stream.close(); + return out.toByteArray(); + } + + private Map> sanitizeHeaders(Map> source) { + if (source == null || source.isEmpty()) { + return Collections.emptyMap(); + } + Map> result = new LinkedHashMap<>(); + for (Map.Entry> entry : source.entrySet()) { + if (entry.getKey() == null) { + continue; + } + result.put(entry.getKey(), entry.getValue()); + } + return result; + } + + private boolean allowsRequestBody(String method) { + if (method == null) { + return false; + } + String upper = method.toUpperCase(); + return "POST".equals(upper) || "PUT".equals(upper) || "PATCH".equals(upper) || "DELETE".equals(upper); + } + + private HostnameVerifier createHostnameVerifier(final String originalHost) { + if (options.isAllowInsecureCertificatesForDebugOnly()) { + return new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + } + + final HostnameVerifier defaultVerifier = HttpsURLConnection.getDefaultHostnameVerifier(); + return new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return defaultVerifier.verify(originalHost, session); + } + }; + } + + private SSLSocketFactory createSocketFactory() throws IOException { + try { + SSLSocketFactory baseFactory; + if (options.isAllowInsecureCertificatesForDebugOnly()) { + baseFactory = trustAllSocketFactory(); + } else { + baseFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); + } + return new NoSniSocketFactory(baseFactory); + } catch (GeneralSecurityException e) { + throw new IOException("create ssl socket factory failed", e); + } + } + + private SSLSocketFactory trustAllSocketFactory() throws GeneralSecurityException { + TrustManager[] managers = new TrustManager[]{new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }}; + + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, managers, new SecureRandom()); + return context.getSocketFactory(); + } + + private static class NoSniSocketFactory extends SSLSocketFactory { + private final SSLSocketFactory delegate; + + private NoSniSocketFactory(SSLSocketFactory delegate) { + this.delegate = delegate; + } + + @Override + public String[] getDefaultCipherSuites() { + return delegate.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + @Override + public java.net.Socket createSocket(java.net.Socket s, String host, int port, boolean autoClose) + throws IOException { + return sanitize(delegate.createSocket(s, host, port, autoClose)); + } + + @Override + public java.net.Socket createSocket(String host, int port) throws IOException { + return sanitize(delegate.createSocket(host, port)); + } + + @Override + public java.net.Socket createSocket(String host, int port, java.net.InetAddress localHost, int localPort) + throws IOException { + return sanitize(delegate.createSocket(host, port, localHost, localPort)); + } + + @Override + public java.net.Socket createSocket(java.net.InetAddress host, int port) throws IOException { + return sanitize(delegate.createSocket(host, port)); + } + + @Override + public java.net.Socket createSocket(java.net.InetAddress address, int port, java.net.InetAddress localAddress, + int localPort) throws IOException { + return sanitize(delegate.createSocket(address, port, localAddress, localPort)); + } + + private java.net.Socket sanitize(java.net.Socket socket) { + if (!(socket instanceof SSLSocket)) { + return socket; + } + SSLSocket sslSocket = (SSLSocket) socket; + try { + SSLParameters params = sslSocket.getSSLParameters(); + try { + java.lang.reflect.Method setServerNames = SSLParameters.class.getMethod("setServerNames", List.class); + setServerNames.invoke(params, Collections.emptyList()); + } catch (Throwable ignored) { + } + sslSocket.setSSLParameters(params); + } catch (Throwable ignored) { + } + return sslSocket; + } + } +} diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/request/HttpRequest.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/request/HttpRequest.java index 1084eaf..d59d2b8 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/request/HttpRequest.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/request/HttpRequest.java @@ -7,9 +7,7 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; -import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSession; import com.alibaba.sdk.android.httpdns.log.HttpDnsLog; @@ -61,13 +59,7 @@ public class HttpRequest { //设置通用UA conn.setRequestProperty("User-Agent", requestConfig.getUA()); if (conn instanceof HttpsURLConnection) { - ((HttpsURLConnection)conn).setHostnameVerifier(new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return HttpsURLConnection.getDefaultHostnameVerifier().verify( - HttpRequestConfig.HTTPS_CERTIFICATE_HOSTNAME, session); - } - }); + ((HttpsURLConnection) conn).setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()); } if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { in = conn.getErrorStream(); diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostHelper.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostHelper.java index 9d9aa62..a66a06a 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostHelper.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostHelper.java @@ -1,25 +1,22 @@ package com.alibaba.sdk.android.httpdns.resolve; -import android.os.Build; import android.text.TextUtils; -import java.io.UnsupportedEncodingException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - import com.alibaba.sdk.android.httpdns.BuildConfig; import com.alibaba.sdk.android.httpdns.NetType; import com.alibaba.sdk.android.httpdns.RequestIpType; import com.alibaba.sdk.android.httpdns.impl.AESEncryptService; import com.alibaba.sdk.android.httpdns.impl.HttpDnsConfig; import com.alibaba.sdk.android.httpdns.impl.SignService; -import com.alibaba.sdk.android.httpdns.log.HttpDnsLog; import com.alibaba.sdk.android.httpdns.request.HttpRequestConfig; import com.alibaba.sdk.android.httpdns.track.SessionTrackMgr; -import org.json.JSONObject; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; public class ResolveHostHelper { public static HttpRequestConfig getConfig(HttpDnsConfig config, String host, @@ -28,18 +25,18 @@ public class ResolveHostHelper { Map globalParams, SignService signService, AESEncryptService encryptService) { - HashMap extraArgs = null; - if (cacheKey != null) { - extraArgs = new HashMap<>(); + HashMap mergedExtras = null; + if ((globalParams != null && !globalParams.isEmpty()) || (extras != null && !extras.isEmpty())) { + mergedExtras = new HashMap<>(); if (globalParams != null) { - extraArgs.putAll(globalParams); + mergedExtras.putAll(globalParams); } if (extras != null) { - extraArgs.putAll(extras); + mergedExtras.putAll(extras); } } - String path = getPath(config, host, type, extraArgs, signService, encryptService); + String path = getPath(config, host, type, mergedExtras, signService, encryptService); HttpRequestConfig requestConfig = getHttpRequestConfig(config, path, signService.isSignMode()); requestConfig.setUA(config.getUA()); requestConfig.setAESEncryptService(encryptService); @@ -50,202 +47,62 @@ public class ResolveHostHelper { Map extras, SignService signService, AESEncryptService encryptService) { - //参数加密 - String enc = ""; - String query = getQuery(type); - String version = "1.0"; - String tags = config.getBizTags(); - AESEncryptService.EncryptionMode mode = AESEncryptService.EncryptionMode.PLAIN; - if (encryptService.isEncryptionMode()) { - String encryptJson = buildEncryptionStr(host, query, extras, tags); - if (HttpDnsLog.isPrint()) { - HttpDnsLog.d("encryptJson:" + encryptJson); - } - mode = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? AESEncryptService.EncryptionMode.AES_GCM : AESEncryptService.EncryptionMode.AES_CBC; - enc = encryptService.encrypt(encryptJson, mode); + String qtype = getQType(type); + StringBuilder query = new StringBuilder(); + appendQuery(query, "appId", config.getAccountId()); + appendQuery(query, "dn", host); + appendQuery(query, "qtype", qtype); + appendQuery(query, "sdk_version", BuildConfig.VERSION_NAME); + appendQuery(query, "os", "android"); + String sid = SessionTrackMgr.getInstance().getSessionId(); + if (!TextUtils.isEmpty(sid)) { + appendQuery(query, "sid", sid); } - - String expireTime = signService.getExpireTime(); - - String queryStr = buildQueryStr(config.getAccountId(), mode.getMode(), host, - query, extras, enc, expireTime, version, tags); - if (HttpDnsLog.isPrint()) { - HttpDnsLog.d("query parameter:" + queryStr); - } - - //加签 - if (signService.isSignMode()) { - Map signParamMap = new HashMap<>(); - if (encryptService.isEncryptionMode()) { - signParamMap.put("enc", enc); - signParamMap.put("exp", expireTime); - signParamMap.put("id", config.getAccountId()); - signParamMap.put("m", mode.getMode()); - signParamMap.put("v", version); - }else { - signParamMap.put("dn", host); - signParamMap.put("exp", expireTime); - signParamMap.put("id", config.getAccountId()); - signParamMap.put("m", mode.getMode()); - if (!TextUtils.isEmpty(query)) { - signParamMap.put("q", query); - } - if (extras != null) { - for (Map.Entry entry : extras.entrySet()) { - signParamMap.put("sdns-" + entry.getKey(), entry.getValue()); - } - } - if (!TextUtils.isEmpty(tags)) { - signParamMap.put("tags", tags); - } - signParamMap.put("v", version); - } - - String sign = signService.sign(signParamMap); - if (TextUtils.isEmpty(sign)) { - if (HttpDnsLog.isPrint()) { - HttpDnsLog.d("param sign fail"); - } - }else { - if (HttpDnsLog.isPrint()) { - HttpDnsLog.d("sign:" + sign); - } - queryStr += "&s=" + sign; - } - } - String path = "/v2/d?" + queryStr + "&sdk=android_" + BuildConfig.VERSION_NAME + getSid(); - if (HttpDnsLog.isPrint()) { - HttpDnsLog.d("path:" + path); - } - return path; - } - - private static String buildQueryStr(String accountId, String mode, String host, - String query, Map extras, String enc, - String expireTime, String version, String tags) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("id=").append(accountId); - stringBuilder.append("&m=").append(mode); - if (TextUtils.isEmpty(enc)) { - stringBuilder.append("&dn=").append(host); - if (!TextUtils.isEmpty(query)) { - stringBuilder.append("&q=").append(query); - } - - String extra = getExtra(extras); - if (!TextUtils.isEmpty(extra)) { - stringBuilder.append(extra); - } - if (!TextUtils.isEmpty(tags)) { - stringBuilder.append("&tags=").append(tags); - } - }else { - stringBuilder.append("&enc=").append(enc); - } - stringBuilder.append("&v=").append(version); - stringBuilder.append("&exp=").append(expireTime); - return stringBuilder.toString(); - } - - private static String buildEncryptionStr(String host, String query, Map extras, String tags) { - JSONObject json = new JSONObject(); - try { - json.put("dn", host); - if (!TextUtils.isEmpty(query)) { - json.put("q", query); - } - if (!TextUtils.isEmpty(getExtra(extras))) { - for (Map.Entry entry : extras.entrySet()) { - if (!checkKey(entry.getKey()) || !checkValue(entry.getValue())) { - continue; - } - json.put("sdns-" + entry.getKey(), entry.getValue()); - } - } - if (!TextUtils.isEmpty(tags)) { - json.put("tags", tags); - } - } catch (Exception e) { - if (HttpDnsLog.isPrint()) { - HttpDnsLog.e("encrypt param transfer to json fail.", e); - } - - } - return json.toString(); - } - - private static String getQuery(RequestIpType type) { - String query = ""; - switch (type) { - case v6: - query = "6"; - break; - case both: - query = "4,6"; - break; - default: - break; - } - return query; - } - - private static String getExtra(Map extras) { - StringBuilder sb = new StringBuilder(); - boolean isKey = true; - boolean isValue = true; if (extras != null) { - for (Map.Entry entry : extras.entrySet()) { - sb.append("&sdns-"); - sb.append(entry.getKey()); - sb.append("="); - sb.append(entry.getValue()); - if (!checkKey(entry.getKey())) { - isKey = false; - HttpDnsLog.e("设置自定义参数失败,自定义key不合法:" + entry.getKey()); - break; - } - if (!checkValue(entry.getValue())) { - isValue = false; - HttpDnsLog.e("设置自定义参数失败,自定义value不合法:" + entry.getValue()); - break; - } + String cip = extras.get("cip"); + if (!TextUtils.isEmpty(cip)) { + appendQuery(query, "cip", cip); } - } else { - return ""; } - if (isKey && isValue) { - String extra = sb.toString(); - if (extra.getBytes(StandardCharsets.UTF_8).length <= 1000) { - return extra; - } else { - HttpDnsLog.e("设置自定义参数失败,自定义参数过长"); - return ""; - } - } else { - return ""; + if (signService.isSignMode()) { + String exp = signService.getExpireTime(); + String nonce = randomNonce(); + String sign = signService.signResolve(config.getAccountId(), host, qtype, exp, nonce); + appendQuery(query, "exp", exp); + appendQuery(query, "nonce", nonce); + appendQuery(query, "sign", sign); } + return "/resolve?" + query; } - private static boolean checkKey(String s) { - return s.matches("[a-zA-Z0-9\\-_]+"); + private static void appendQuery(StringBuilder query, String key, String value) { + if (TextUtils.isEmpty(key) || value == null) { + return; + } + if (query.length() > 0) { + query.append("&"); + } + query.append(key).append("=").append(URLEncoder.encode(value, StandardCharsets.UTF_8)); } - private static boolean checkValue(String s) { - return s.matches("[a-zA-Z0-9\\-_=]+"); + private static String getQType(RequestIpType type) { + if (type == RequestIpType.v6) { + return "AAAA"; + } + return "A"; + } + + private static String randomNonce() { + return UUID.randomUUID().toString().replace("-", ""); } public static HttpRequestConfig getConfig(HttpDnsConfig config, ArrayList hostList, RequestIpType type, SignService signService, AESEncryptService encryptService) { - //拼接host - StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < hostList.size(); i++) { - if (i != 0) { - stringBuilder.append(","); - } - stringBuilder.append(hostList.get(i)); + String host = ""; + if (hostList != null && hostList.size() > 0) { + host = hostList.get(0); } - String host = stringBuilder.toString(); String path = getPath(config, host, type, null, signService, encryptService); HttpRequestConfig requestConfig = getHttpRequestConfig(config, path, signService.isSignMode()); requestConfig.setUA(config.getUA()); @@ -268,14 +125,6 @@ public class ResolveHostHelper { } } - public static String getTags(HttpDnsConfig config) { - if (TextUtils.isEmpty(config.getBizTags())) { - return ""; - } - - return "&tags=" + config.getBizTags(); - } - public static String getSid() { String sessionId = SessionTrackMgr.getInstance().getSessionId(); if (sessionId == null) { @@ -284,4 +133,14 @@ public class ResolveHostHelper { return "&sid=" + sessionId; } } + + /** + * 兼容可观测模块透传 tags。 + */ + public static String getTags(HttpDnsConfig config) { + if (config == null || TextUtils.isEmpty(config.getBizTags())) { + return ""; + } + return "&tags=" + config.getBizTags(); + } } diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostRequestHandler.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostRequestHandler.java index 14c2bf2..7154b62 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostRequestHandler.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostRequestHandler.java @@ -1,23 +1,18 @@ package com.alibaba.sdk.android.httpdns.resolve; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - import com.alibaba.sdk.android.httpdns.RequestIpType; import com.alibaba.sdk.android.httpdns.impl.AESEncryptService; import com.alibaba.sdk.android.httpdns.impl.HttpDnsConfig; import com.alibaba.sdk.android.httpdns.impl.SignService; import com.alibaba.sdk.android.httpdns.log.HttpDnsLog; -import com.alibaba.sdk.android.httpdns.request.BatchResolveHttpRequestStatusWatcher; -import com.alibaba.sdk.android.httpdns.request.HttpRequest; import com.alibaba.sdk.android.httpdns.request.HttpRequestConfig; -import com.alibaba.sdk.android.httpdns.request.HttpRequestTask; -import com.alibaba.sdk.android.httpdns.request.HttpRequestWatcher; import com.alibaba.sdk.android.httpdns.request.RequestCallback; -import com.alibaba.sdk.android.httpdns.request.RetryHttpRequest; import com.alibaba.sdk.android.httpdns.serverip.RegionServerScheduleService; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + /** * 发起域名解析请求 */ @@ -43,9 +38,18 @@ public class ResolveHostRequestHandler { public void requestResolveHost(final String host, final RequestIpType type, Map extras, final String cacheKey, RequestCallback callback) { + if (type == RequestIpType.both) { + requestResolveHostBoth(host, extras, cacheKey, callback); + return; + } + requestResolveHostSingle(host, type, extras, cacheKey, callback); + } + + private void requestResolveHostSingle(final String host, final RequestIpType type, + Map extras, final String cacheKey, + RequestCallback callback) { HttpRequestConfig requestConfig = ResolveHostHelper.getConfig(mHttpDnsConfig, host, type, extras, cacheKey, mGlobalParams, mSignService, mAESEncryptService); - //补充可观测数据 requestConfig.setResolvingHost(host); requestConfig.setResolvingIpType(type); if (HttpDnsLog.isPrint()) { @@ -54,30 +58,140 @@ public class ResolveHostRequestHandler { mCategoryController.getCategory().resolve(mHttpDnsConfig, requestConfig, callback); } + private void requestResolveHostBoth(final String host, + final Map extras, + final String cacheKey, + final RequestCallback callback) { + final ArrayList mergedItems = new ArrayList<>(); + final String[] serverIpHolder = new String[]{""}; + final Throwable[] errorHolder = new Throwable[]{null}; + + requestResolveHostSingle(host, RequestIpType.v4, extras, cacheKey, new RequestCallback() { + @Override + public void onSuccess(ResolveHostResponse resolveHostResponse) { + mergeResponse(resolveHostResponse, mergedItems, serverIpHolder); + requestResolveHostSingle(host, RequestIpType.v6, extras, cacheKey, new RequestCallback() { + @Override + public void onSuccess(ResolveHostResponse resolveHostResponse) { + mergeResponse(resolveHostResponse, mergedItems, serverIpHolder); + finishBothResolve(callback, mergedItems, serverIpHolder[0], errorHolder[0]); + } + + @Override + public void onFail(Throwable throwable) { + if (errorHolder[0] == null) { + errorHolder[0] = throwable; + } + finishBothResolve(callback, mergedItems, serverIpHolder[0], errorHolder[0]); + } + }); + } + + @Override + public void onFail(Throwable throwable) { + errorHolder[0] = throwable; + requestResolveHostSingle(host, RequestIpType.v6, extras, cacheKey, new RequestCallback() { + @Override + public void onSuccess(ResolveHostResponse resolveHostResponse) { + mergeResponse(resolveHostResponse, mergedItems, serverIpHolder); + finishBothResolve(callback, mergedItems, serverIpHolder[0], errorHolder[0]); + } + + @Override + public void onFail(Throwable throwable) { + if (errorHolder[0] == null) { + errorHolder[0] = throwable; + } + finishBothResolve(callback, mergedItems, serverIpHolder[0], errorHolder[0]); + } + }); + } + }); + } + + private void mergeResponse(ResolveHostResponse response, + ArrayList mergedItems, + String[] serverIpHolder) { + if (response == null) { + return; + } + if (response.getItems() != null && !response.getItems().isEmpty()) { + mergedItems.addAll(response.getItems()); + } + if (serverIpHolder[0].isEmpty() && response.getServerIp() != null) { + serverIpHolder[0] = response.getServerIp(); + } + } + + private void finishBothResolve(RequestCallback callback, + ArrayList mergedItems, + String serverIp, + Throwable error) { + if (callback == null) { + return; + } + if (!mergedItems.isEmpty()) { + callback.onSuccess(new ResolveHostResponse(mergedItems, serverIp)); + return; + } + if (error != null) { + callback.onFail(error); + return; + } + callback.onSuccess(new ResolveHostResponse(new ArrayList(), serverIp)); + } + public void requestResolveHost(final ArrayList hostList, final RequestIpType type, RequestCallback callback) { - HttpRequestConfig requestConfig = ResolveHostHelper.getConfig(mHttpDnsConfig, hostList, - type, mSignService, mAESEncryptService); - requestConfig.setResolvingIpType(type); + if (callback == null) { + return; + } + if (hostList == null || hostList.isEmpty()) { + callback.onSuccess(new ResolveHostResponse(new ArrayList(), "")); + return; + } if (HttpDnsLog.isPrint()) { HttpDnsLog.d("start resolve hosts async for " + hostList.toString() + " " + type); } - HttpRequest request = new HttpRequest<>( - requestConfig, new ResolveHostResponseParser(mAESEncryptService)); - request = new HttpRequestWatcher<>(request, - new BatchResolveHttpRequestStatusWatcher(mHttpDnsConfig.getObservableManager())); - // 切换服务IP,更新服务IP - request = new HttpRequestWatcher<>(request, new ShiftServerWatcher(mHttpDnsConfig, - mScheduleService, mCategoryController)); - // 重试一次 - request = new RetryHttpRequest<>(request, 1); - try { - mHttpDnsConfig.getResolveWorker().execute( - new HttpRequestTask<>(request, callback)); - } catch (Throwable e) { - callback.onFail(e); + final ArrayList allItems = new ArrayList<>(); + final String[] serverIpHolder = new String[]{""}; + requestResolveHostsSequentially(hostList, 0, type, allItems, serverIpHolder, callback); + } + + private void requestResolveHostsSequentially(final ArrayList hostList, + final int index, + final RequestIpType type, + final ArrayList allItems, + final String[] serverIpHolder, + final RequestCallback callback) { + if (index >= hostList.size()) { + callback.onSuccess(new ResolveHostResponse(allItems, serverIpHolder[0])); + return; } + final String host = hostList.get(index); + requestResolveHost(host, type, null, null, new RequestCallback() { + @Override + public void onSuccess(ResolveHostResponse resolveHostResponse) { + if (resolveHostResponse != null) { + if (resolveHostResponse.getItems() != null) { + allItems.addAll(resolveHostResponse.getItems()); + } + if (serverIpHolder[0].isEmpty()) { + serverIpHolder[0] = resolveHostResponse.getServerIp(); + } + } + requestResolveHostsSequentially(hostList, index + 1, type, allItems, serverIpHolder, callback); + } + + @Override + public void onFail(Throwable throwable) { + if (HttpDnsLog.isPrint()) { + HttpDnsLog.w("batch resolve host fail: " + host, throwable); + } + requestResolveHostsSequentially(hostList, index + 1, type, allItems, serverIpHolder, callback); + } + }); } /** @@ -88,14 +202,14 @@ public class ResolveHostRequestHandler { } /** - * 设置嗅探模式的请求时间间隔 + * 设置嗅探模式请求时间间隔 */ public void setSniffTimeInterval(int timeInterval) { mCategoryController.setSniffTimeInterval(timeInterval); } /** - * 设置sdns的全局参数 + * 设置 SDNS 全局参数(当前服务端不使用,保留兼容) */ public void setSdnsGlobalParams(Map params) { this.mGlobalParams.clear(); @@ -105,10 +219,9 @@ public class ResolveHostRequestHandler { } /** - * 清除sdns的全局参数 + * 清除 SDNS 全局参数 */ public void clearSdnsGlobalParams() { this.mGlobalParams.clear(); } - } diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostResponse.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostResponse.java index 6643418..6e107eb 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostResponse.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostResponse.java @@ -10,6 +10,7 @@ import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; /** @@ -122,78 +123,47 @@ public class ResolveHostResponse { } public static ResolveHostResponse fromResponse(String serverIp, String body) throws JSONException { - ArrayList items = new ArrayList<>(); - JSONObject jsonObject = new JSONObject(body); - - if (jsonObject.has("answers")) { - JSONArray answers = jsonObject.getJSONArray("answers"); - for (int i = 0; i < answers.length(); i++) { - JSONObject answer = answers.getJSONObject(i); - String hostName = null; - int ttl = 0; - String extra = null; - String[] ips = null; - String[] ipsv6 = null; - String noIpCode = null; - if (answer.has("dn")) { - hostName = answer.getString("dn"); + JSONObject responseObject = new JSONObject(body); + JSONObject data = responseObject.optJSONObject("data"); + if (data == null) { + return new ResolveHostResponse(items, serverIp); + } + String hostName = data.optString("domain"); + int ttl = data.optInt("ttl", 60); + String summary = data.optString("summary", null); + JSONArray records = data.optJSONArray("records"); + HashMap> typedIPs = new HashMap<>(); + if (records != null) { + for (int i = 0; i < records.length(); i++) { + JSONObject record = records.optJSONObject(i); + if (record == null) { + continue; } - - if (answer.has("v4")) { - JSONObject ipv4 = answer.getJSONObject("v4"); - if (ipv4.has("ips")) { - JSONArray ipArray = ipv4.getJSONArray("ips"); - if (ipArray.length() != 0) { - ips = new String[ipArray.length()]; - for (int j = 0; j < ipArray.length(); j++) { - ips[j] = ipArray.getString(j); - } - } - } - if (ipv4.has("ttl")) { - ttl = ipv4.getInt("ttl"); - } - if (ipv4.has("extra")) { - extra = ipv4.getString("extra"); - } - if (ipv4.has("no_ip_code")) { - noIpCode = ipv4.getString("no_ip_code"); - } - items.add(new HostItem(hostName, RequestIpType.v4, ips, ttl, extra, noIpCode)); - if (!TextUtils.isEmpty(noIpCode)) { - HttpDnsLog.w("RESOLVE FAIL, HOST:" + hostName + ", QUERY:4, " - + "Msg:" + noIpCode); - } + String ip = record.optString("ip"); + if (TextUtils.isEmpty(ip)) { + continue; } - if (answer.has("v6")) { - JSONObject ipv6 = answer.getJSONObject("v6"); - if (ipv6.has("ips")) { - JSONArray ipArray = ipv6.getJSONArray("ips"); - if (ipArray.length() != 0) { - ipsv6 = new String[ipArray.length()]; - for (int j = 0; j < ipArray.length(); j++) { - ipsv6[j] = ipArray.getString(j); - } - } - } - if (ipv6.has("ttl")) { - ttl = ipv6.getInt("ttl"); - } - if (ipv6.has("extra")) { - extra = ipv6.getString("extra"); - } - if (ipv6.has("no_ip_code")) { - noIpCode = ipv6.getString("no_ip_code"); - } - items.add(new HostItem(hostName, RequestIpType.v6, ipsv6, ttl, extra, noIpCode)); - if (!TextUtils.isEmpty(noIpCode)) { - HttpDnsLog.w("RESOLVE FAIL, HOST:" + hostName + ", QUERY:6, " - + "Msg:" + noIpCode); - } + String recordType = record.optString("type", data.optString("qtype", "A")).toUpperCase(); + RequestIpType ipType = "AAAA".equals(recordType) ? RequestIpType.v6 : RequestIpType.v4; + ArrayList list = typedIPs.get(ipType); + if (list == null) { + list = new ArrayList<>(); + typedIPs.put(ipType, list); } + list.add(ip); + } + } + if (typedIPs.isEmpty()) { + String qtype = data.optString("qtype", "A"); + RequestIpType ipType = "AAAA".equalsIgnoreCase(qtype) ? RequestIpType.v6 : RequestIpType.v4; + items.add(new HostItem(hostName, ipType, null, ttl, summary, null)); + } else { + for (RequestIpType type : typedIPs.keySet()) { + ArrayList ipList = typedIPs.get(type); + String[] ips = ipList == null ? null : ipList.toArray(new String[0]); + items.add(new HostItem(hostName, type, ips, ttl, summary, null)); } - } return new ResolveHostResponse(items, serverIp); } diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostResponseParser.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostResponseParser.java index 9f372c8..68f1538 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostResponseParser.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/main/java/com/alibaba/sdk/android/httpdns/resolve/ResolveHostResponseParser.java @@ -1,68 +1,27 @@ package com.alibaba.sdk.android.httpdns.resolve; -import android.text.TextUtils; - import com.alibaba.sdk.android.httpdns.impl.AESEncryptService; -import com.alibaba.sdk.android.httpdns.log.HttpDnsLog; import com.alibaba.sdk.android.httpdns.request.ResponseParser; import org.json.JSONObject; -public class ResolveHostResponseParser implements - ResponseParser { - - private final AESEncryptService mAESEncryptService; +public class ResolveHostResponseParser implements ResponseParser { public ResolveHostResponseParser(AESEncryptService aesEncryptService) { - mAESEncryptService = aesEncryptService; + // 新版协议固定 HTTPS,不使用 AES 响应体解密,保留构造参数仅为兼容调用方。 } @Override public ResolveHostResponse parse(String serverIp, String response) throws Throwable { - String data = ""; - JSONObject jsonResponse = new JSONObject(response); - if (jsonResponse.has("code")) { - String code = jsonResponse.getString("code"); - if (TextUtils.equals(code, "success")) { - if (jsonResponse.has("data")) { - data = jsonResponse.getString("data"); - if (!TextUtils.isEmpty(data)) { - //解密 - AESEncryptService.EncryptionMode mode = AESEncryptService.EncryptionMode.PLAIN; - if (jsonResponse.has("mode")) { - String serverEncryptMode = jsonResponse.getString("mode"); - if (TextUtils.equals(serverEncryptMode, AESEncryptService.EncryptionMode.AES_GCM.getMode())) { - mode = AESEncryptService.EncryptionMode.AES_GCM; - } else if (TextUtils.equals(serverEncryptMode, AESEncryptService.EncryptionMode.AES_CBC.getMode())) { - mode = AESEncryptService.EncryptionMode.AES_CBC; - } - } - data = mAESEncryptService.decrypt(data, mode); - if (TextUtils.isEmpty(data)) { - if (HttpDnsLog.isPrint()) { - HttpDnsLog.e("response data decrypt fail"); - } - } - } else { - if (HttpDnsLog.isPrint()) { - HttpDnsLog.e("response data is empty"); - } - } - } - } else { - if (HttpDnsLog.isPrint()) { - HttpDnsLog.e("解析失败,原因为" + code); - } - throw new Exception(code); - } - }else { - if (HttpDnsLog.isPrint()) { - HttpDnsLog.e("response don't have code"); + JSONObject responseObject = new JSONObject(response); + String code = responseObject.optString("code"); + if (!"SUCCESS".equalsIgnoreCase(code)) { + String message = responseObject.optString("message"); + if (message == null) { + message = ""; } + throw new Exception(code + ":" + message); } - if (HttpDnsLog.isPrint()) { - HttpDnsLog.d("request success " + data); - } - return ResolveHostResponse.fromResponse(serverIp, data); + return ResolveHostResponse.fromResponse(serverIp, response); } } diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/normal/java/com/alibaba/sdk/android/httpdns/HttpDns.java b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/normal/java/com/alibaba/sdk/android/httpdns/HttpDns.java index b346b93..7712d51 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/src/normal/java/com/alibaba/sdk/android/httpdns/HttpDns.java +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/src/normal/java/com/alibaba/sdk/android/httpdns/HttpDns.java @@ -4,6 +4,8 @@ import android.content.Context; import com.alibaba.sdk.android.httpdns.impl.HttpDnsInstanceHolder; import com.alibaba.sdk.android.httpdns.impl.InstanceCreator; +import com.alibaba.sdk.android.httpdns.network.HttpDnsAdapterOptions; +import com.alibaba.sdk.android.httpdns.network.HttpDnsHttpAdapter; import com.alibaba.sdk.android.httpdns.utils.CommonUtil; /** @@ -74,6 +76,20 @@ public class HttpDns { InitConfig.addConfig(accountId, config); } + /** + * Build official IP-direct + empty-SNI adapter. + */ + public static HttpDnsHttpAdapter buildHttpClientAdapter(HttpDnsService service) { + return new HttpDnsHttpAdapter(service); + } + + /** + * Build official IP-direct + empty-SNI adapter with options. + */ + public static HttpDnsHttpAdapter buildHttpClientAdapter(HttpDnsService service, HttpDnsAdapterOptions options) { + return new HttpDnsHttpAdapter(service, options); + } + /** * 启用或者禁用httpdns,理论上这个是内部接口,不给外部使用的 * 但是已经对外暴露,所以保留 diff --git a/EdgeHttpDNS/sdk/android/httpdns-sdk/version.gradle b/EdgeHttpDNS/sdk/android/httpdns-sdk/version.gradle index 3ea9a58..8b051e5 100644 --- a/EdgeHttpDNS/sdk/android/httpdns-sdk/version.gradle +++ b/EdgeHttpDNS/sdk/android/httpdns-sdk/version.gradle @@ -1,8 +1,8 @@ ext { - httpdnsDebugVersion = '2.6.7' + httpdnsDebugVersion = '1.0.0' loggerVersion = '1.2.0' crashDefendVersion = '0.0.6' utdidVersion = '2.6.0' ipdetectorVersion = '1.2.0' -} \ No newline at end of file +} diff --git a/EdgeHttpDNS/sdk/build_packages.sh b/EdgeHttpDNS/sdk/build_packages.sh new file mode 100644 index 0000000..c81b350 --- /dev/null +++ b/EdgeHttpDNS/sdk/build_packages.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +set -e + +ROOT=$(cd "$(dirname "$0")" && pwd) +DIST_DIR="$ROOT/dist" +TMP_DIR="$ROOT/.tmp_sdk_pkg" + +function lookup_version() { + VERSION_FILE="$ROOT/../internal/const/const.go" + if [ ! -f "$VERSION_FILE" ]; then + echo "0.0.0" + return + fi + VERSION=$(grep -E 'Version[[:space:]]*=' "$VERSION_FILE" | head -n 1 | sed -E 's/.*"([0-9.]+)".*/\1/') + if [ -z "$VERSION" ]; then + echo "0.0.0" + else + echo "$VERSION" + fi +} + +function ensure_cmd() { + CMD=$1 + if ! command -v "$CMD" >/dev/null 2>&1; then + echo "missing command: $CMD" + exit 1 + fi +} + +function zip_dir() { + SRC_DIR=$1 + ZIP_FILE=$2 + ( + cd "$SRC_DIR" || exit 1 + zip -r -X -q "$ZIP_FILE" . + ) +} + +function build_android_sdk_package() { + echo "[sdk] building android aar ..." + ensure_cmd zip + if [ ! -x "$ROOT/android/gradlew" ]; then + echo "android gradlew not found: $ROOT/android/gradlew" + exit 1 + fi + + ( + cd "$ROOT/android" || exit 1 + ./gradlew :httpdns-sdk:clean :httpdns-sdk:assembleNormalRelease + ) + + AAR_FILE=$(find "$ROOT/android/httpdns-sdk/build/outputs/aar" -type f -name "*normal-release*.aar" | head -n 1) + if [ -z "$AAR_FILE" ]; then + AAR_FILE=$(find "$ROOT/android/httpdns-sdk/build/outputs/aar" -type f -name "*release*.aar" | head -n 1) + fi + if [ -z "$AAR_FILE" ] || [ ! -f "$AAR_FILE" ]; then + echo "android aar is not generated" + exit 1 + fi + + PKG_DIR="$TMP_DIR/android" + rm -rf "$PKG_DIR" + mkdir -p "$PKG_DIR" + cp "$AAR_FILE" "$PKG_DIR/alicloud-android-httpdns.aar" + if [ -f "$ROOT/android/README.md" ]; then + cp "$ROOT/android/README.md" "$PKG_DIR/README.md" + fi + if [ -f "$ROOT/android/httpdns-sdk/proguard-rules.pro" ]; then + cp "$ROOT/android/httpdns-sdk/proguard-rules.pro" "$PKG_DIR/proguard-rules.pro" + fi + + zip_dir "$PKG_DIR" "$DIST_DIR/httpdns-sdk-android.zip" +} + +function build_ios_sdk_package() { + echo "[sdk] packaging ios xcframework ..." + ensure_cmd zip + + CANDIDATES=( + "$ROOT/ios/dist/AlicloudHttpDNS.xcframework" + "$ROOT/ios/AlicloudHttpDNS.xcframework" + "$ROOT/ios/Build/AlicloudHttpDNS.xcframework" + ) + + XCFRAMEWORK_DIR="" + for path in "${CANDIDATES[@]}"; do + if [ -d "$path" ]; then + XCFRAMEWORK_DIR="$path" + break + fi + done + + if [ -z "$XCFRAMEWORK_DIR" ]; then + echo "ios xcframework not found." + echo "please build it on macOS first, then place AlicloudHttpDNS.xcframework under EdgeHttpDNS/sdk/ios/dist/" + exit 1 + fi + + PKG_DIR="$TMP_DIR/ios" + rm -rf "$PKG_DIR" + mkdir -p "$PKG_DIR" + cp -R "$XCFRAMEWORK_DIR" "$PKG_DIR/" + if [ -f "$ROOT/ios/AlicloudHTTPDNS.podspec" ]; then + cp "$ROOT/ios/AlicloudHTTPDNS.podspec" "$PKG_DIR/" + fi + if [ -f "$ROOT/ios/README.md" ]; then + cp "$ROOT/ios/README.md" "$PKG_DIR/README.md" + fi + + zip_dir "$PKG_DIR" "$DIST_DIR/httpdns-sdk-ios.zip" +} + +function build_flutter_sdk_package() { + echo "[sdk] packaging flutter plugin ..." + ensure_cmd zip + PLUGIN_DIR="$ROOT/flutter/aliyun_httpdns" + if [ ! -d "$PLUGIN_DIR" ]; then + echo "flutter plugin directory not found: $PLUGIN_DIR" + exit 1 + fi + + PKG_DIR="$TMP_DIR/flutter" + rm -rf "$PKG_DIR" + mkdir -p "$PKG_DIR" + cp -R "$PLUGIN_DIR" "$PKG_DIR/" + rm -rf "$PKG_DIR/aliyun_httpdns/example/.dart_tool" "$PKG_DIR/aliyun_httpdns/example/build" "$PKG_DIR/aliyun_httpdns/.dart_tool" "$PKG_DIR/aliyun_httpdns/build" + + zip_dir "$PKG_DIR" "$DIST_DIR/httpdns-sdk-flutter.zip" +} + +function main() { + VERSION=$(lookup_version) + rm -rf "$TMP_DIR" + mkdir -p "$TMP_DIR" "$DIST_DIR" + + build_android_sdk_package + build_ios_sdk_package + build_flutter_sdk_package + + cp "$DIST_DIR/httpdns-sdk-android.zip" "$DIST_DIR/httpdns-sdk-android-v${VERSION}.zip" + cp "$DIST_DIR/httpdns-sdk-ios.zip" "$DIST_DIR/httpdns-sdk-ios-v${VERSION}.zip" + cp "$DIST_DIR/httpdns-sdk-flutter.zip" "$DIST_DIR/httpdns-sdk-flutter-v${VERSION}.zip" + + rm -rf "$TMP_DIR" + echo "[sdk] done. output: $DIST_DIR" +} + +main "$@" + diff --git a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/README.md b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/README.md index ae94f12..9b3c76e 100644 --- a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/README.md +++ b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/README.md @@ -1,532 +1,73 @@ -# Aliyun HTTPDNS Flutter Plugin +# HTTPDNS Flutter SDK (SNI Hidden v1.0.0) -阿里云EMAS HTTPDNS Flutter插件,提供基于原生SDK的域名解析能力。 - -一、快速入门 ------------------------ - -### 1.1 开通服务 - -请参考[快速入门文档](https://help.aliyun.com/document_detail/2867674.html)开通HTTPDNS。 - -### 1.2 获取配置 - -请参考开发配置文档在EMAS控制台开发配置中获取AccountId/SecretKey/AESSecretKey等信息,用于初始化SDK。 - -## 二、安装 - -在`pubspec.yaml`中加入dependencies: -```yaml -dependencies: - aliyun_httpdns: ^1.0.1 -``` -添加依赖之后需要执行一次 `flutter pub get`。 - -### 原生SDK版本说明 - -插件已集成了对应平台的HTTPDNS原生SDK,当前版本: - -- **Android**: `com.aliyun.ams:alicloud-android-httpdns:2.6.7` -- **iOS**: `AlicloudHTTPDNS:3.3.0` - - - -三、配置和使用 ------------------------- - -### 3.1 初始化配置 - -应用启动后,需要先初始化插件,才能调用HTTPDNS能力。 -初始化主要是配置AccountId/SecretKey等信息及功能开关。 -示例代码如下: +## 1. Initialization ```dart -// 初始化 HTTPDNS -await AliyunHttpdns.init( - accountId: '您的AccountId', - secretKey: '您的SecretKey', -); - -// 设置功能选项 -await AliyunHttpdns.setHttpsRequestEnabled(true); -await AliyunHttpdns.setLogEnabled(true); -await AliyunHttpdns.setPersistentCacheIPEnabled(true); -await AliyunHttpdns.setReuseExpiredIPEnabled(true); - -// 构建服务 -await AliyunHttpdns.build(); - -// 设置预解析域名 -await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com'], ipType: 'both'); -print("init success"); -``` - - - -#### 3.1.1 日志配置 - -应用开发过程中,如果要输出HTTPDNS的日志,可以调用日志输出控制方法,开启日志,示例代码如下: - -```dart -await AliyunHttpdns.setLogEnabled(true); -print("enableLog success"); -``` - - - -#### 3.1.2 sessionId记录 - -应用在运行过程中,可以调用获取SessionId方法获取sessionId,记录到应用的数据采集系统中。 -sessionId用于表示标识一次应用运行,线上排查时,可以用于查询应用一次运行过程中的解析日志,示例代码如下: - -```dart -final sessionId = await AliyunHttpdns.getSessionId(); -print("SessionId = $sessionId"); -``` - - - -### 3.2 域名解析 - -#### 3.2.1 预解析 - -当需要提前解析域名时,可以调用预解析域名方法,示例代码如下: - -```dart -await AliyunHttpdns.setPreResolveHosts(["www.aliyun.com", "www.example.com"], ipType: 'both'); -print("preResolveHosts success"); -``` - - - -调用之后,插件会发起域名解析,并把结果缓存到内存,用于后续请求时直接使用。 - -### 3.2.2 域名解析 - -当需要解析域名时,可以通过调用域名解析方法解析域名获取IP,示例代码如下: - -```dart -Future _resolve() async { - final res = await AliyunHttpdns.resolveHostSyncNonBlocking('www.aliyun.com', ipType: 'both'); - final ipv4List = res['ipv4'] ?? []; - final ipv6List = res['ipv6'] ?? []; - print('IPv4: $ipv4List'); - print('IPv6: $ipv6List'); -} -``` - - - -四、Flutter最佳实践 ------------------------------- - -### 4.1 原理说明 - -本示例展示了一种更直接的集成方式,通过自定义HTTP客户端适配器来实现HTTPDNS集成: - -1. 创建自定义的HTTP客户端适配器,拦截网络请求 -2. 在适配器中调用HTTPDNS插件解析域名为IP地址 -3. 使用解析得到的IP地址创建直接的Socket连接 -4. 对于HTTPS连接,确保正确设置SNI(Server Name Indication)为原始域名 - -这种方式避免了创建本地代理服务的复杂性,直接在HTTP客户端层面集成HTTPDNS功能。 - -### 4.2 示例说明 - -完整应用示例请参考插件包中example应用。 - -#### 4.2.1 自定义HTTP客户端适配器实现 - -自定义适配器的实现请参考插件包中example/lib/net/httpdns_http_client_adapter.dart文件。本方案由EMAS团队设计实现,参考请注明出处。 -适配器内部会拦截HTTP请求,调用HTTPDNS进行域名解析,并使用解析后的IP创建socket连接。 - -本示例支持三种网络库:Dio、HttpClient、http包。代码如下: - -```dart -import 'dart:io'; -import 'package:dio/io.dart'; -import 'package:http/http.dart' as http; -import 'package:http/io_client.dart'; -import 'package:flutter/foundation.dart'; import 'package:aliyun_httpdns/aliyun_httpdns.dart'; -// Dio 适配器 -IOHttpClientAdapter buildHttpdnsHttpClientAdapter() { - final HttpClient client = HttpClient(); - _configureHttpClient(client); - _configureConnectionFactory(client); - - final IOHttpClientAdapter adapter = IOHttpClientAdapter(createHttpClient: () => client) - ..validateCertificate = (cert, host, port) => true; - return adapter; -} - -// 原生 HttpClient -HttpClient buildHttpdnsNativeHttpClient() { - final HttpClient client = HttpClient(); - _configureHttpClient(client); - _configureConnectionFactory(client); - return client; -} - -// http 包适配器 -http.Client buildHttpdnsHttpPackageClient() { - final HttpClient httpClient = buildHttpdnsNativeHttpClient(); - return IOClient(httpClient); -} - -// HttpClient 基础配置 -void _configureHttpClient(HttpClient client) { - client.findProxy = (Uri _) => 'DIRECT'; - client.idleTimeout = const Duration(seconds: 90); - client.maxConnectionsPerHost = 8; -} - -// 配置基于 HTTPDNS 的连接工厂 -// 本方案由EMAS团队设计实现,参考请注明出处。 -void _configureConnectionFactory(HttpClient client) { - client.connectionFactory = (Uri uri, String? proxyHost, int? proxyPort) async { - final String domain = uri.host; - final bool https = uri.scheme.toLowerCase() == 'https'; - final int port = uri.port == 0 ? (https ? 443 : 80) : uri.port; - - final List targets = await _resolveTargets(domain); - final Object target = targets.isNotEmpty ? targets.first : domain; - - if (!https) { - return Socket.startConnect(target, port); - } - - // HTTPS:先 TCP,再 TLS(SNI=域名),并保持可取消 - bool cancelled = false; - final Future> rawStart = Socket.startConnect(target, port); - final Future upgraded = rawStart.then((task) async { - final Socket raw = await task.socket; - if (cancelled) { - raw.destroy(); - throw const SocketException('Connection cancelled'); - } - final SecureSocket secure = await SecureSocket.secure( - raw, - host: domain, // 重要:使用原始域名作为SNI - ); - if (cancelled) { - secure.destroy(); - throw const SocketException('Connection cancelled'); - } - return secure; - }); - return ConnectionTask.fromSocket( - upgraded, - () { - cancelled = true; - try { - rawStart.then((t) => t.cancel()); - } catch (_) {} - }, - ); - }; -} - -// 通过 HTTPDNS 解析目标 IP 列表 -Future> _resolveTargets(String domain) async { - try { - final res = await AliyunHttpdns.resolveHostSyncNonBlocking(domain, ipType: 'both'); - final List ipv4 = res['ipv4'] ?? []; - final List ipv6 = res['ipv6'] ?? []; - final List targets = [ - ...ipv4.map(InternetAddress.tryParse).whereType(), - ...ipv6.map(InternetAddress.tryParse).whereType(), - ]; - if (targets.isEmpty) { - debugPrint('[dio] HTTPDNS no result for $domain, fallback to system DNS'); - } else { - debugPrint('[dio] HTTPDNS resolved $domain -> ${targets.first.address}'); - } - return targets; - } catch (e) { - debugPrint('[dio] HTTPDNS resolve failed: $e, fallback to system DNS'); - return const []; - } -} -``` - - - -#### 4.2.2 适配器集成和使用 - -适配器的集成请参考插件包中example/lib/main.dart文件。 -首先需要初始化HTTPDNS,然后配置网络库使用自定义适配器,示例代码如下: - -```dart -class _MyHomePageState extends State { - late final Dio _dio; - late final HttpClient _httpClient; - late final http.Client _httpPackageClient; - - @override - void initState() { - super.initState(); - - // 初始化 HTTPDNS - _initHttpDnsOnce(); - - // 配置网络库使用 HTTPDNS 适配器 - _dio = Dio(); - _dio.httpClientAdapter = buildHttpdnsHttpClientAdapter(); - _dio.options.headers['Connection'] = 'keep-alive'; - - _httpClient = buildHttpdnsNativeHttpClient(); - _httpPackageClient = buildHttpdnsHttpPackageClient(); - } - - Future _initHttpDnsOnce() async { - try { - await AliyunHttpdns.init( - accountId: 000000, - secretKey: '您的SecretKey', - ); - await AliyunHttpdns.setHttpsRequestEnabled(true); - await AliyunHttpdns.setLogEnabled(true); - await AliyunHttpdns.setPersistentCacheIPEnabled(true); - await AliyunHttpdns.setReuseExpiredIPEnabled(true); - await AliyunHttpdns.build(); - - // 设置预解析域名 - await AliyunHttpdns.setPreResolveHosts(['www.aliyun.com'], ipType: 'both'); - } catch (e) { - debugPrint('[httpdns] init failed: $e'); - } - } -} -``` - - - -使用配置好的网络库发起请求时,会自动使用HTTPDNS进行域名解析: - -```dart -// 使用 Dio -final response = await _dio.get('https://www.aliyun.com'); - -// 使用 HttpClient -final request = await _httpClient.getUrl(Uri.parse('https://www.aliyun.com')); -final response = await request.close(); - -// 使用 http 包 -final response = await _httpPackageClient.get(Uri.parse('https://www.aliyun.com')); -``` - -#### 4.2.3 资源清理 - -在组件销毁时,记得清理相关资源: - -```dart -@override -void dispose() { - _urlController.dispose(); - _httpClient.close(); - _httpPackageClient.close(); - super.dispose(); -} -``` - - - -五、API ----------------------- - -### 5.1 日志输出控制 - -控制是否打印Log。 - -```dart -await AliyunHttpdns.setLogEnabled(true); -print("enableLog success"); -``` - - - -### 5.2 初始化 - -初始化配置, 在应用启动时调用。 - -```dart -// 基础初始化 await AliyunHttpdns.init( - accountId: 000000, - secretKey: 'your_secret_key', - aesSecretKey: 'your_aes_secret_key', // 可选 + appId: 'app1f1ndpo9', + primaryServiceHost: 'httpdns-a.example.com', + backupServiceHost: 'httpdns-b.example.com', // optional + servicePort: 443, + secretKey: 'your-sign-secret', // optional if sign is enabled ); -// 配置功能选项 await AliyunHttpdns.setHttpsRequestEnabled(true); -await AliyunHttpdns.setLogEnabled(true); -await AliyunHttpdns.setPersistentCacheIPEnabled(true); -await AliyunHttpdns.setReuseExpiredIPEnabled(true); - -// 构建服务实例 await AliyunHttpdns.build(); - -print("init success"); ``` - - -初始化参数: - -| 参数名 | 类型 | 是否必须 | 功能 | 支持平台 | -|-------------|--------|------|------------|-------------| -| accountId | int | 必选参数 | Account ID | Android/iOS | -| secretKey | String | 可选参数 | 加签密钥 | Android/iOS | -| aesSecretKey| String | 可选参数 | 加密密钥 | Android/iOS | - -功能配置方法: - -- `setHttpsRequestEnabled(bool)` - 设置是否使用HTTPS解析链路 -- `setLogEnabled(bool)` - 设置是否开启日志 -- `setPersistentCacheIPEnabled(bool)` - 设置是否开启持久化缓存 -- `setReuseExpiredIPEnabled(bool)` - 设置是否允许复用过期IP -- `setPreResolveAfterNetworkChanged(bool)` - 设置网络切换时是否自动刷新解析 - - - -### 5.3 域名解析 - -解析指定域名。 +## 2. Resolve ```dart -Future _resolve() async { - final res = await AliyunHttpdns.resolveHostSyncNonBlocking( - 'www.aliyun.com', - ipType: 'both', // 'auto', 'ipv4', 'ipv6', 'both' - ); - - final ipv4List = res['ipv4'] ?? []; - final ipv6List = res['ipv6'] ?? []; - print('IPv4: $ipv4List'); - print('IPv6: $ipv6List'); -} -``` - - - -参数: - -| 参数名 | 类型 | 是否必须 | 功能 | -|------------|---------------------|------|----------------------------------------| -| hostname | String | 必选参数 | 要解析的域名 | -| ipType | String | 可选参数 | 请求IP类型: 'auto', 'ipv4', 'ipv6', 'both' | - - - -返回数据结构: - -| 字段名 | 类型 | 功能 | -|------|--------------|----------------------------------| -| ipv4 | List | IPv4地址列表,如: ["1.1.1.1", "2.2.2.2"] | -| ipv6 | List | IPv6地址列表,如: ["::1", "::2"] | - - - -### 5.4 预解析域名 - -预解析域名, 解析后缓存在SDK中,下次解析时直接从缓存中获取,提高解析速度。 - -```dart -await AliyunHttpdns.setPreResolveHosts( - ["www.aliyun.com", "www.example.com"], - ipType: 'both' +final result = await AliyunHttpdns.resolveHostSyncNonBlocking( + 'api.business.com', + ipType: 'both', ); -print("preResolveHosts success"); + +final ipv4 = result['ipv4'] ?? []; +final ipv6 = result['ipv6'] ?? []; ``` - - -参数: - -| 参数名 | 类型 | 是否必须 | 功能 | -|--------|--------------|------|----------------------------------------| -| hosts | List | 必选参数 | 预解析域名列表 | -| ipType | String | 可选参数 | 请求IP类型: 'auto', 'ipv4', 'ipv6', 'both' | - - - -### 5.5 获取SessionId - -获取SessionId, 用于排查追踪问题。 +## 3. Official HTTP Adapter (IP + Host) ```dart -final sessionId = await AliyunHttpdns.getSessionId(); -print("SessionId = $sessionId"); -``` - - - -无需参数,直接返回当前会话ID。 - -### 5.6 清除缓存 - -清除所有DNS解析缓存。 - -```dart -await AliyunHttpdns.cleanAllHostCache(); -print("缓存清除成功"); -``` - -### 5.7 持久化缓存配置 - -设置是否开启持久化缓存功能。开启后,SDK 会将解析结果保存到本地,App 重启后可以从本地加载缓存,提升首屏加载速度。 - -```dart -// 基础用法:开启持久化缓存 -await AliyunHttpdns.setPersistentCacheIPEnabled(true); - -// 高级用法:开启持久化缓存并设置过期时间阈值 -await AliyunHttpdns.setPersistentCacheIPEnabled( - true, - discardExpiredAfterSeconds: 86400 // 1天,单位:秒 +final adapter = AliyunHttpdns.createHttpAdapter( + options: const AliyunHttpdnsAdapterOptions( + ipType: 'auto', + connectTimeoutMs: 3000, + readTimeoutMs: 5000, + allowInsecureCertificatesForDebugOnly: false, + ), ); -print("持久化缓存已开启"); + +final resp = await adapter.request( + Uri.parse('https://api.business.com/v1/ping'), + method: 'GET', + headers: {'Accept': 'application/json'}, +); + +print(resp.statusCode); +print(resp.usedIp); ``` -参数: +Behavior is fixed: +- Resolve host by `/resolve`. +- Connect to resolved IP over HTTPS. +- Keep `Host` header as the real business domain. +- No fallback to domain direct request. -| 参数名 | 类型 | 是否必须 | 功能 | -|----------------------------|------|------|------------------------------------------| -| enabled | bool | 必选参数 | 是否开启持久化缓存 | -| discardExpiredAfterSeconds | int | 可选参数 | 过期时间阈值(秒),App 启动时会丢弃过期超过此时长的缓存记录,建议设置为 1 天(86400 秒) | - -注意事项: -- 持久化缓存仅影响第一次域名解析结果,后续解析仍会请求 HTTPDNS 服务器 -- 如果业务服务器 IP 变化频繁,建议谨慎开启此功能 -- 建议在 `build()` 之前调用此接口 - -### 5.8 网络变化时自动刷新预解析 - -设置在网络环境变化时是否自动刷新预解析域名的缓存。 - -```dart -await AliyunHttpdns.setPreResolveAfterNetworkChanged(true); -print("网络变化自动刷新已启用"); -``` - -### 5.9 IP 优选 - -设置需要进行 IP 优选的域名列表。开启后,SDK 会对解析返回的 IP 列表进行 TCP 测速并排序,优先返回连接速度最快的 IP。 - -```dart -await AliyunHttpdns.setIPRankingList({ - 'www.aliyun.com': 443, -}); -print("IP 优选配置成功"); -``` - -参数: - -| 参数名 | 类型 | 是否必须 | 功能 | -|-------------|-----------------|------|------------------------------| -| hostPortMap | Map | 必选参数 | 域名和端口的映射,例如:{'www.aliyun.com': 443} | +## 4. Public Errors +- `NO_IP_AVAILABLE` +- `TLS_EMPTY_SNI_FAILED` +- `HOST_ROUTE_REJECTED` +- `RESOLVE_SIGN_INVALID` +## 5. Deprecated Params Removed +The public init API no longer accepts: +- `accountId` +- `serviceDomain` +- `endpoint` +- `aesSecretKey` diff --git a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/android/src/main/kotlin/com/aliyun/ams/httpdns/AliyunHttpDnsPlugin.kt b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/android/src/main/kotlin/com/aliyun/ams/httpdns/AliyunHttpDnsPlugin.kt index c114374..13b2470 100644 --- a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/android/src/main/kotlin/com/aliyun/ams/httpdns/AliyunHttpDnsPlugin.kt +++ b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/android/src/main/kotlin/com/aliyun/ams/httpdns/AliyunHttpDnsPlugin.kt @@ -3,7 +3,6 @@ package com.aliyun.ams.httpdns import android.content.Context import android.util.Log import androidx.annotation.NonNull - import com.alibaba.sdk.android.httpdns.HttpDns import com.alibaba.sdk.android.httpdns.HttpDnsService import com.alibaba.sdk.android.httpdns.InitConfig @@ -15,18 +14,18 @@ import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result - class AliyunHttpDnsPlugin : FlutterPlugin, MethodCallHandler { private lateinit var channel: MethodChannel private var appContext: Context? = null - // Cached service keyed by accountId to avoid re-creating private var service: HttpDnsService? = null - private var accountId: String? = null - private var secretKey: String? = null - private var aesSecretKey: String? = null - // Desired states collected before build() + private var appId: String? = null + private var secretKey: String? = null + private var primaryServiceHost: String? = null + private var backupServiceHost: String? = null + private var servicePort: Int? = null + private var desiredPersistentCacheEnabled: Boolean? = null private var desiredDiscardExpiredAfterSeconds: Int? = null private var desiredReuseExpiredIPEnabled: Boolean? = null @@ -35,10 +34,6 @@ class AliyunHttpDnsPlugin : FlutterPlugin, MethodCallHandler { private var desiredPreResolveAfterNetworkChanged: Boolean? = null private var desiredIPRankingMap: Map? = null - - - - override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { appContext = flutterPluginBinding.applicationContext channel = MethodChannel(flutterPluginBinding.binaryMessenger, "aliyun_httpdns") @@ -46,14 +41,7 @@ class AliyunHttpDnsPlugin : FlutterPlugin, MethodCallHandler { } override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { - // Log every incoming call with method name and raw arguments - try { - Log.i("AliyunHttpDns", "invoke method=${call.method}, args=${call.arguments}") - } catch (_: Throwable) { - Log.i("AliyunHttpDns", "invoke method=${call.method}, args=") - } when (call.method) { - // Dart: init(accountId, secretKey?, aesSecretKey?) — only save states here "initialize" -> { val args = call.arguments as? Map<*, *> ?: emptyMap() val ctx = appContext @@ -61,261 +49,315 @@ class AliyunHttpDnsPlugin : FlutterPlugin, MethodCallHandler { result.error("no_context", "Android context not attached", null) return } - val accountAny = args["accountId"] - val account = when (accountAny) { - is Int -> accountAny.toString() - is Long -> accountAny.toString() - is String -> accountAny - else -> null - } - val secret = (args["secretKey"] as? String)?.takeIf { it.isNotBlank() } - val aes = (args["aesSecretKey"] as? String)?.takeIf { it.isNotBlank() } - if (account.isNullOrBlank()) { - Log.i("AliyunHttpDns", "initialize missing accountId") + val appIdAny = args["appId"] + val parsedAppId = when (appIdAny) { + is Int -> appIdAny.toString() + is Long -> appIdAny.toString() + is String -> appIdAny.trim() + else -> "" + } + if (parsedAppId.isBlank()) { + Log.i("AliyunHttpDns", "initialize missing appId") result.success(false) return } - // Save desired states only; actual build happens on 'build' - accountId = account + + val primaryHostArg = (args["primaryServiceHost"] as? String)?.trim() + if (primaryHostArg.isNullOrBlank()) { + Log.i("AliyunHttpDns", "initialize missing primaryServiceHost") + result.success(false) + return + } + + val secret = (args["secretKey"] as? String)?.takeIf { it.isNotBlank() } + val backup = (args["backupServiceHost"] as? String)?.trim() + val port = when (val portAny = args["servicePort"]) { + is Int -> portAny + is Long -> portAny.toInt() + is String -> portAny.toIntOrNull() + else -> null + } + + appId = parsedAppId secretKey = secret - aesSecretKey = aes - Log.i("AliyunHttpDns", "initialize saved state, account=$account") + primaryServiceHost = primaryHostArg + backupServiceHost = backup?.trim()?.takeIf { it.isNotEmpty() } + servicePort = if (port != null && port > 0) port else null + + Log.i( + "AliyunHttpDns", + "initialize appId=$appId, primaryServiceHost=$primaryServiceHost, backupServiceHost=$backupServiceHost, servicePort=$servicePort" + ) result.success(true) } - - - // Dart: setLogEnabled(enabled) — save desired "setLogEnabled" -> { val enabled = call.argument("enabled") == true desiredLogEnabled = enabled - Log.i("AliyunHttpDns", "setLogEnabled desired=$enabled") result.success(null) } - // Dart: setHttpsRequestEnabled(enabled) "setHttpsRequestEnabled" -> { val enabled = call.argument("enabled") == true desiredHttpsEnabled = enabled - Log.i("AliyunHttpDns", "https request desired=$enabled") result.success(null) } - // Dart: setPersistentCacheIPEnabled(enabled, discardExpiredAfterSeconds?) — save desired "setPersistentCacheIPEnabled" -> { val enabled = call.argument("enabled") == true val discard = call.argument("discardExpiredAfterSeconds") desiredPersistentCacheEnabled = enabled desiredDiscardExpiredAfterSeconds = discard - Log.i("AliyunHttpDns", "persistent cache desired=$enabled discard=$discard") result.success(null) } - // Dart: setReuseExpiredIPEnabled(enabled) — save desired "setReuseExpiredIPEnabled" -> { val enabled = call.argument("enabled") == true desiredReuseExpiredIPEnabled = enabled - Log.i("AliyunHttpDns", "reuse expired ip desired=$enabled") result.success(null) } - // Dart: setPreResolveAfterNetworkChanged(enabled) — save desired (applied at build via InitConfig) "setPreResolveAfterNetworkChanged" -> { val enabled = call.argument("enabled") == true desiredPreResolveAfterNetworkChanged = enabled - Log.i("AliyunHttpDns", "preResolveAfterNetworkChanged desired=$enabled") result.success(null) } - // Dart: setIPRankingList(hostPortMap) — save desired "setIPRankingList" -> { val hostPortMap = call.argument>("hostPortMap") desiredIPRankingMap = hostPortMap - Log.i("AliyunHttpDns", "IP ranking list desired, hosts=${hostPortMap?.keys?.joinToString()}") result.success(null) } - // Dart: setPreResolveHosts(hosts, ipType) "setPreResolveHosts" -> { val hosts = call.argument>("hosts") ?: emptyList() - val ipTypeStr = call.argument("ipType") ?: "auto" - val type = when (ipTypeStr.lowercase()) { - "ipv4", "v4" -> RequestIpType.v4 - "ipv6", "v6" -> RequestIpType.v6 - "both", "64" -> RequestIpType.both - else -> RequestIpType.auto - } + val type = mapIpType(call.argument("ipType") ?: "auto") try { service?.setPreResolveHosts(hosts, type) - Log.i("AliyunHttpDns", "preResolve set for ${hosts.size} hosts, type=$type") - } catch (t: Throwable) { - Log.i("AliyunHttpDns", "setPreResolveHosts failed: ${t.message}") + } catch (_: Throwable) { } result.success(null) } - // Dart: getSessionId "getSessionId" -> { - val sid = try { service?.getSessionId() } catch (_: Throwable) { null } + val sid = try { + service?.getSessionId() + } catch (_: Throwable) { + null + } result.success(sid) } - // Dart: cleanAllHostCache "cleanAllHostCache" -> { try { - // Best-effort: empty list to clear all service?.cleanHostCache(ArrayList()) - } catch (t: Throwable) { - Log.i("AliyunHttpDns", "cleanAllHostCache failed: ${t.message}") + } catch (_: Throwable) { } result.success(null) } - // Dart: build() — construct InitConfig and acquire service using desired states "build" -> { val ctx = appContext - val account = accountId - if (ctx == null || account.isNullOrBlank()) { + val currentAppId = appId + if (ctx == null || currentAppId.isNullOrBlank()) { result.success(false) return } - try { - desiredLogEnabled?.let { enabled -> - try { - HttpDnsLog.enable(enabled) - Log.i("AliyunHttpDns", "HttpDnsLog.enable($enabled)") - } catch (t: Throwable) { - Log.w("AliyunHttpDns", "HttpDnsLog.enable failed: ${t.message}") - } - } - - val builder = InitConfig.Builder() - // Optional builder params - try { builder.javaClass.getMethod("setContext", Context::class.java).invoke(builder, ctx) } catch (_: Throwable) {} + try { + desiredLogEnabled?.let { HttpDnsLog.enable(it) } + + val builder = InitConfig.Builder() + var hostConfigApplied = false + try { + builder.javaClass.getMethod("setContext", Context::class.java) + .invoke(builder, ctx) + } catch (_: Throwable) { + } try { if (!secretKey.isNullOrBlank()) { - builder.javaClass.getMethod("setSecretKey", String::class.java).invoke(builder, secretKey) + builder.javaClass.getMethod("setSecretKey", String::class.java) + .invoke(builder, secretKey) } - } catch (_: Throwable) {} + } catch (_: Throwable) { + } try { - if (!aesSecretKey.isNullOrBlank()) { - builder.javaClass.getMethod("setAesSecretKey", String::class.java).invoke(builder, aesSecretKey) - } - } catch (_: Throwable) {} - // Prefer HTTPS if requested + val enableHttps = desiredHttpsEnabled ?: true + builder.javaClass.getMethod("setEnableHttps", Boolean::class.javaPrimitiveType) + .invoke(builder, enableHttps) + } catch (_: Throwable) { + } + try { - desiredHttpsEnabled?.let { en -> - builder.javaClass.getMethod("setEnableHttps", Boolean::class.javaPrimitiveType).invoke(builder, en) + builder.javaClass.getMethod("setPrimaryServiceHost", String::class.java) + .invoke(builder, primaryServiceHost) + hostConfigApplied = true + } catch (t: Throwable) { + Log.w("AliyunHttpDns", "setPrimaryServiceHost failed: ${t.message}") + } + try { + backupServiceHost?.let { + builder.javaClass.getMethod("setBackupServiceHost", String::class.java) + .invoke(builder, it) } - } catch (_: Throwable) {} + } catch (_: Throwable) { + } + try { + servicePort?.let { + builder.javaClass.getMethod("setServicePort", Int::class.javaPrimitiveType) + .invoke(builder, it) + } + } catch (_: Throwable) { + } + try { desiredPersistentCacheEnabled?.let { enabled -> val discardSeconds = desiredDiscardExpiredAfterSeconds if (discardSeconds != null && discardSeconds >= 0) { - val expiredThresholdMillis = discardSeconds.toLong() * 1000L - builder.javaClass.getMethod("setEnableCacheIp", Boolean::class.javaPrimitiveType, Long::class.javaPrimitiveType) - .invoke(builder, enabled, expiredThresholdMillis) + val thresholdMillis = discardSeconds.toLong() * 1000L + builder.javaClass.getMethod( + "setEnableCacheIp", + Boolean::class.javaPrimitiveType, + Long::class.javaPrimitiveType + ).invoke(builder, enabled, thresholdMillis) } else { - builder.javaClass.getMethod("setEnableCacheIp", Boolean::class.javaPrimitiveType) - .invoke(builder, enabled) + builder.javaClass.getMethod( + "setEnableCacheIp", + Boolean::class.javaPrimitiveType + ).invoke(builder, enabled) } } - } catch (_: Throwable) { } + } catch (_: Throwable) { + } + try { - desiredReuseExpiredIPEnabled?.let { enabled -> + desiredReuseExpiredIPEnabled?.let { builder.javaClass.getMethod("setEnableExpiredIp", Boolean::class.javaPrimitiveType) - .invoke(builder, enabled) + .invoke(builder, it) } - } catch (_: Throwable) { } - // Apply preResolve-after-network-changed + } catch (_: Throwable) { + } + try { - desiredPreResolveAfterNetworkChanged?.let { en -> - builder.javaClass.getMethod("setPreResolveAfterNetworkChanged", Boolean::class.javaPrimitiveType).invoke(builder, en) + desiredPreResolveAfterNetworkChanged?.let { + builder.javaClass.getMethod("setPreResolveAfterNetworkChanged", Boolean::class.javaPrimitiveType) + .invoke(builder, it) } - } catch (_: Throwable) {} - - // Apply IP ranking list + } catch (_: Throwable) { + } + try { desiredIPRankingMap?.let { map -> if (map.isNotEmpty()) { - // Create List - val ipRankingBeanClass = Class.forName("com.alibaba.sdk.android.httpdns.ranking.IPRankingBean") - val constructor = ipRankingBeanClass.getConstructor(String::class.java, Int::class.javaPrimitiveType) + val beanClass = Class.forName("com.alibaba.sdk.android.httpdns.ranking.IPRankingBean") + val ctor = beanClass.getConstructor(String::class.java, Int::class.javaPrimitiveType) val list = ArrayList() map.forEach { (host, port) -> - val bean = constructor.newInstance(host, port) - list.add(bean) + list.add(ctor.newInstance(host, port)) } - val m = builder.javaClass.getMethod("setIPRankingList", List::class.java) - m.invoke(builder, list) - Log.i("AliyunHttpDns", "setIPRankingList applied with ${list.size} hosts") + builder.javaClass.getMethod("setIPRankingList", List::class.java) + .invoke(builder, list) } } - } catch (t: Throwable) { - Log.w("AliyunHttpDns", "setIPRankingList failed: ${t.message}") + } catch (_: Throwable) { } - builder.buildFor(account) + if (!hostConfigApplied) { + Log.w("AliyunHttpDns", "build failed: sdk core does not support primaryServiceHost") + result.success(false) + return + } + + builder.buildFor(currentAppId) service = if (!secretKey.isNullOrBlank()) { - HttpDns.getService(ctx, account, secretKey) + HttpDns.getService(ctx, currentAppId, secretKey) } else { - HttpDns.getService(ctx, account) + HttpDns.getService(ctx, currentAppId) } - - Log.i("AliyunHttpDns", "build completed for account=$account") + result.success(true) } catch (t: Throwable) { - Log.i("AliyunHttpDns", "build failed: ${t.message}") + Log.w("AliyunHttpDns", "build failed: ${t.message}") result.success(false) } } - // Dart: resolveHostSyncNonBlocking(hostname, ipType, sdnsParams?, cacheKey?) "resolveHostSyncNonBlocking" -> { val hostname = call.argument("hostname") if (hostname.isNullOrBlank()) { result.success(mapOf("ipv4" to emptyList(), "ipv6" to emptyList())) return } - val ipTypeStr = call.argument("ipType") ?: "auto" - val type = when (ipTypeStr.lowercase()) { - "ipv4", "v4" -> RequestIpType.v4 - "ipv6", "v6" -> RequestIpType.v6 - "both", "64" -> RequestIpType.both - else -> RequestIpType.auto - } + + val type = mapIpType(call.argument("ipType") ?: "auto") try { val svc = service ?: run { val ctx = appContext - val acc = accountId - if (ctx != null && !acc.isNullOrBlank()) HttpDns.getService(ctx, acc) else null + val currentAppId = appId + if (ctx != null && !currentAppId.isNullOrBlank()) { + HttpDns.getService(ctx, currentAppId) + } else { + null + } } val r = svc?.getHttpDnsResultForHostSyncNonBlocking(hostname, type) val v4 = r?.ips?.toList() ?: emptyList() val v6 = r?.ipv6s?.toList() ?: emptyList() - // 记录解析结果,便于排查:包含 host、请求类型以及返回的 IPv4/IPv6 列表 - Log.d( - "HttpdnsPlugin", - "resolve result host=" + hostname + ", type=" + type + - ", ipv4=" + v4.joinToString(prefix = "[", postfix = "]") + - ", ipv6=" + v6.joinToString(prefix = "[", postfix = "]") - ) result.success(mapOf("ipv4" to v4, "ipv6" to v6)) - } catch (t: Throwable) { - Log.i("AliyunHttpDns", "resolveHostSyncNonBlocking failed: ${t.message}") + } catch (_: Throwable) { result.success(mapOf("ipv4" to emptyList(), "ipv6" to emptyList())) } } - - // Legacy methods removed: preResolve / clearCache handled at app layer if needed + "resolveHostV1" -> { + val hostname = call.argument("hostname") + if (hostname.isNullOrBlank()) { + result.success(mapOf("ipv4" to emptyList(), "ipv6" to emptyList(), "ttl" to 0)) + return + } + val qtype = (call.argument("qtype") ?: "A").uppercase() + val cip = call.argument("cip")?.trim() + val requestType = if (qtype == "AAAA") RequestIpType.v6 else RequestIpType.v4 + try { + val svc = service ?: run { + val ctx = appContext + val currentAppId = appId + if (ctx != null && !currentAppId.isNullOrBlank()) { + HttpDns.getService(ctx, currentAppId) + } else { + null + } + } + val params = if (!cip.isNullOrEmpty()) mapOf("cip" to cip) else null + val r = svc?.getHttpDnsResultForHostSyncNonBlocking(hostname, requestType, params, hostname) + val v4 = r?.ips?.toList() ?: emptyList() + val v6 = r?.ipv6s?.toList() ?: emptyList() + result.success( + mapOf( + "ipv4" to v4, + "ipv6" to v6, + "ttl" to (r?.ttl ?: 0), + ) + ) + } catch (_: Throwable) { + result.success(mapOf("ipv4" to emptyList(), "ipv6" to emptyList(), "ttl" to 0)) + } + } else -> result.notImplemented() } } + private fun mapIpType(ipType: String): RequestIpType { + return when (ipType.lowercase()) { + "ipv4", "v4" -> RequestIpType.v4 + "ipv6", "v6" -> RequestIpType.v6 + "both", "64" -> RequestIpType.both + else -> RequestIpType.auto + } + } + override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { channel.setMethodCallHandler(null) service = null diff --git a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/example/README.md b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/example/README.md index 15a0808..79abf46 100644 --- a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/example/README.md +++ b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/example/README.md @@ -16,11 +16,14 @@ This example demonstrates: ## Getting Started -1. Replace the `accountId` and `secretKey` in `lib/main.dart` with your own credentials: +1. Replace the SDK init parameters in `lib/main.dart` with your own values: ```dart await AliyunHttpdns.init( - accountId: YOUR_ACCOUNT_ID, // Replace with your account ID - secretKey: 'YOUR_SECRET_KEY', // Replace with your secret key + appId: 'YOUR_APP_ID', + primaryServiceHost: 'httpdns-a.example.com', + backupServiceHost: 'httpdns-b.example.com', + servicePort: 443, + secretKey: 'YOUR_SIGN_SECRET', // optional if sign is enabled ); ``` @@ -48,4 +51,4 @@ The example uses a modern approach with `HttpClient.connectionFactory` to integr ## Note -The credentials in this example are placeholders. Please obtain your own credentials from the [Aliyun HTTPDNS Console](https://help.aliyun.com/document_detail/2867674.html). +The values in this example are placeholders. Use your own platform app configuration. diff --git a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/example/lib/main.dart b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/example/lib/main.dart index 54902b4..ae47b8f 100644 --- a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/example/lib/main.dart +++ b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/example/lib/main.dart @@ -64,8 +64,11 @@ class _MyHomePageState extends State { _httpdnsIniting = true; try { await AliyunHttpdns.init( - accountId: 000000, // 请替换为您的 Account ID - secretKey: 'your_secret_key_here', // 请替换为您的 Secret Key + appId: 'app1f1ndpo9', // 请替换为您的应用 AppId + primaryServiceHost: 'httpdns-a.example.com', // 请替换为主服务域名 + backupServiceHost: 'httpdns-b.example.com', // 可选:备服务域名 + servicePort: 443, + secretKey: 'your_sign_secret_here', // 可选:仅验签开启时需要 ); await AliyunHttpdns.setHttpsRequestEnabled(true); await AliyunHttpdns.setLogEnabled(true); diff --git a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/ios/Classes/HttpdnsPlugin.swift b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/ios/Classes/HttpdnsPlugin.swift index 2cd891d..7e7d76b 100644 --- a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/ios/Classes/HttpdnsPlugin.swift +++ b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/ios/Classes/HttpdnsPlugin.swift @@ -1,203 +1,324 @@ import Flutter +import Foundation import UIKit -import AlicloudHTTPDNS +import CommonCrypto public class AliyunHttpDnsPlugin: NSObject, FlutterPlugin { - private var channel: FlutterMethodChannel! + private var appId: String? + private var secretKey: String? + private var primaryServiceHost: String? + private var backupServiceHost: String? + private var servicePort: Int = 443 - // Desired states saved until build() - private var desiredAccountId: Int? - private var desiredSecretKey: String? - private var desiredAesSecretKey: String? - - private var desiredPersistentCacheEnabled: Bool? - private var desiredDiscardExpiredAfterSeconds: Int? - private var desiredReuseExpiredIPEnabled: Bool? private var desiredLogEnabled: Bool? private var desiredHttpsEnabled: Bool? - private var desiredPreResolveAfterNetworkChanged: Bool? - private var desiredIPRankingMap: [String: NSNumber]? - + private var desiredConnectTimeoutSeconds: TimeInterval = 3 + private var desiredReadTimeoutSeconds: TimeInterval = 5 + private lazy var sessionId: String = { + UUID().uuidString.replacingOccurrences(of: "-", with: "") + }() public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "aliyun_httpdns", binaryMessenger: registrar.messenger()) let instance = AliyunHttpDnsPlugin() - instance.channel = channel registrar.addMethodCallDelegate(instance, channel: channel) } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { switch call.method { - // Dart: init(accountId, secretKey?, aesSecretKey?) — only save desired state case "initialize": let options = call.arguments as? [String: Any] ?? [:] - let accountIdAny = options["accountId"] - let secretKey = options["secretKey"] as? String - let aesSecretKey = options["aesSecretKey"] as? String - - guard let accountId = (accountIdAny as? Int) ?? Int((accountIdAny as? String) ?? "") else { - NSLog("AliyunHttpDns: initialize missing accountId") + guard let rawAppId = options["appId"] as? String, + let rawPrimaryHost = options["primaryServiceHost"] as? String else { result(false) return } - desiredAccountId = accountId - desiredSecretKey = secretKey - desiredAesSecretKey = aesSecretKey - NSLog("AliyunHttpDns: initialize saved accountId=\(accountId)") + + let normalizedAppId = rawAppId.trimmingCharacters(in: .whitespacesAndNewlines) + let normalizedPrimaryHost = rawPrimaryHost.trimmingCharacters(in: .whitespacesAndNewlines) + if normalizedAppId.isEmpty || normalizedPrimaryHost.isEmpty { + result(false) + return + } + + appId = normalizedAppId + primaryServiceHost = normalizedPrimaryHost + backupServiceHost = (options["backupServiceHost"] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines) + secretKey = (options["secretKey"] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines) + if let p = options["servicePort"] as? Int, p > 0 { + servicePort = p + } result(true) - - - // Dart: setLogEnabled(enabled) — save desired case "setLogEnabled": let args = call.arguments as? [String: Any] - let enabled = (args?["enabled"] as? Bool) ?? false - desiredLogEnabled = enabled - NSLog("AliyunHttpDns: log desired=\(enabled)") + desiredLogEnabled = (args?["enabled"] as? Bool) ?? false result(nil) case "setHttpsRequestEnabled": let args = call.arguments as? [String: Any] - let enabled = (args?["enabled"] as? Bool) ?? false - desiredHttpsEnabled = enabled - NSLog("AliyunHttpDns: https request desired=\(enabled)") + desiredHttpsEnabled = (args?["enabled"] as? Bool) ?? false result(nil) - // Dart: setPersistentCacheIPEnabled(enabled, discardExpiredAfterSeconds?) — save desired case "setPersistentCacheIPEnabled": - let args = call.arguments as? [String: Any] - let enabled = (args?["enabled"] as? Bool) ?? false - let discard = args?["discardExpiredAfterSeconds"] as? Int - desiredPersistentCacheEnabled = enabled - desiredDiscardExpiredAfterSeconds = discard - NSLog("AliyunHttpDns: persistent cache desired=\(enabled) discard=\(discard ?? -1)") result(nil) - // Dart: setReuseExpiredIPEnabled(enabled) — save desired case "setReuseExpiredIPEnabled": - let args = call.arguments as? [String: Any] - let enabled = (args?["enabled"] as? Bool) ?? false - desiredReuseExpiredIPEnabled = enabled - NSLog("AliyunHttpDns: reuse expired ip desired=\(enabled)") result(nil) case "setPreResolveAfterNetworkChanged": - let args = call.arguments as? [String: Any] - let enabled = (args?["enabled"] as? Bool) ?? false - desiredPreResolveAfterNetworkChanged = enabled - NSLog("AliyunHttpDns: preResolveAfterNetworkChanged desired=\(enabled)") result(nil) case "setIPRankingList": - let args = call.arguments as? [String: Any] - let hostPortMap = args?["hostPortMap"] as? [String: NSNumber] - desiredIPRankingMap = hostPortMap - NSLog("AliyunHttpDns: IP ranking list desired, hosts=\(hostPortMap?.keys.joined(separator: ", ") ?? "")") result(nil) case "setPreResolveHosts": - let args = call.arguments as? [String: Any] - let hosts = (args?["hosts"] as? [String]) ?? [] - let ipTypeStr = (args?["ipType"] as? String) ?? "auto" - switch ipTypeStr.lowercased() { - case "ipv4", "v4": - HttpDnsService.sharedInstance().setPreResolveHosts(hosts, queryIPType: AlicloudHttpDNS_IPType.init(0)) - case "ipv6", "v6": - HttpDnsService.sharedInstance().setPreResolveHosts(hosts, queryIPType: AlicloudHttpDNS_IPType.init(1)) - case "both", "64": - HttpDnsService.sharedInstance().setPreResolveHosts(hosts, queryIPType: AlicloudHttpDNS_IPType.init(2)) - default: - HttpDnsService.sharedInstance().setPreResolveHosts(hosts) - } result(nil) case "getSessionId": - let sid = HttpDnsService.sharedInstance().getSessionId() - result(sid) + result(sessionId) case "cleanAllHostCache": - HttpDnsService.sharedInstance().cleanAllHostCache() result(nil) - // Dart: build() — construct service and apply desired states case "build": - guard let accountId = desiredAccountId else { - result(false) - return + if desiredHttpsEnabled == false { + NSLog("AliyunHttpDns(iOS): HTTPS is required by current protocol, force enabled") } - // Initialize singleton - if let secret = desiredSecretKey, !secret.isEmpty { - if let aes = desiredAesSecretKey, !aes.isEmpty { - _ = HttpDnsService(accountID: accountId, secretKey: secret, aesSecretKey: aes) - } else { - _ = HttpDnsService(accountID: accountId, secretKey: secret) - } - } else { - _ = HttpDnsService(accountID: accountId) // deprecated but acceptable fallback - } - let svc = HttpDnsService.sharedInstance() - // Apply desired runtime flags - if let enable = desiredPersistentCacheEnabled { - if let discard = desiredDiscardExpiredAfterSeconds, discard >= 0 { - svc.setPersistentCacheIPEnabled(enable, discardRecordsHasExpiredFor: TimeInterval(discard)) - } else { - svc.setPersistentCacheIPEnabled(enable) - } - } - if let enable = desiredReuseExpiredIPEnabled { - svc.setReuseExpiredIPEnabled(enable) - } - if let enable = desiredLogEnabled { - svc.setLogEnabled(enable) - } - if let enable = desiredHttpsEnabled { - svc.setHTTPSRequestEnabled(enable) + if desiredLogEnabled == true { + NSLog("AliyunHttpDns(iOS): build success, appId=\(appId ?? "")") } + result(appId != nil && primaryServiceHost != nil) - if let en = desiredPreResolveAfterNetworkChanged { - svc.setPreResolveAfterNetworkChanged(en) - } - if let ipRankingMap = desiredIPRankingMap, !ipRankingMap.isEmpty { - svc.setIPRankingDatasource(ipRankingMap) - } - NSLog("AliyunHttpDns: build completed accountId=\(accountId)") - result(true) - - // Dart: resolveHostSyncNonBlocking(hostname, ipType, sdnsParams?, cacheKey?) case "resolveHostSyncNonBlocking": - guard let args = call.arguments as? [String: Any], let host = args["hostname"] as? String else { + guard let args = call.arguments as? [String: Any], + let hostname = args["hostname"] as? String else { result(["ipv4": [], "ipv6": []]) return } - let ipTypeStr = (args["ipType"] as? String) ?? "auto" - let sdnsParams = args["sdnsParams"] as? [String: String] - let cacheKey = args["cacheKey"] as? String - let type: HttpdnsQueryIPType - switch ipTypeStr.lowercased() { - case "ipv4", "v4": type = .ipv4 - case "ipv6", "v6": type = .ipv6 - case "both", "64": type = .both - default: type = .auto + let ipType = ((args["ipType"] as? String) ?? "auto").lowercased() + resolveHost(hostname: hostname, ipType: ipType) { payload in + result(payload) } - let svc = HttpDnsService.sharedInstance() - var v4: [String] = [] - var v6: [String] = [] - if let params = sdnsParams, let key = cacheKey, let r = svc.resolveHostSyncNonBlocking(host, by: type, withSdnsParams: params, sdnsCacheKey: key) { - if r.hasIpv4Address() { v4 = r.ips } - if r.hasIpv6Address() { v6 = r.ipv6s } - } else if let r = svc.resolveHostSyncNonBlocking(host, by: type) { - if r.hasIpv4Address() { v4 = r.ips } - if r.hasIpv6Address() { v6 = r.ipv6s } + case "resolveHostV1": + guard let args = call.arguments as? [String: Any], + let hostname = args["hostname"] as? String else { + result(["ipv4": [], "ipv6": [], "ttl": 0]) + return + } + let qtype = ((args["qtype"] as? String) ?? "A").uppercased() + let cip = (args["cip"] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines) + resolveSingle(hostname: hostname, qtype: qtype, cip: cip) { records, ttl in + if qtype == "AAAA" { + result(["ipv4": [], "ipv6": records, "ttl": ttl]) + } else { + result(["ipv4": records, "ipv6": [], "ttl": ttl]) + } } - result(["ipv4": v4, "ipv6": v6]) - - // Legacy methods removed: preResolve / clearCache default: result(FlutterMethodNotImplemented) } } + + private func resolveHost(hostname: String, ipType: String, completion: @escaping ([String: [String]]) -> Void) { + let qtypes: [String] + switch ipType { + case "ipv6", "v6": + qtypes = ["AAAA"] + case "both", "64": + qtypes = ["A", "AAAA"] + default: + qtypes = ["A"] + } + + let group = DispatchGroup() + let lock = NSLock() + var ipv4: [String] = [] + var ipv6: [String] = [] + + for qtype in qtypes { + group.enter() + resolveSingle(hostname: hostname, qtype: qtype, cip: nil) { records, _ in + lock.lock() + if qtype == "AAAA" { + ipv6.append(contentsOf: records) + } else { + ipv4.append(contentsOf: records) + } + lock.unlock() + group.leave() + } + } + + group.notify(queue: .main) { + completion([ + "ipv4": Array(Set(ipv4)), + "ipv6": Array(Set(ipv6)) + ]) + } + } + + private func resolveSingle(hostname: String, qtype: String, cip: String?, completion: @escaping ([String], Int) -> Void) { + guard let appId = appId, + let primary = primaryServiceHost else { + completion([], 0) + return + } + + var hosts: [String] = [primary] + if let backup = backupServiceHost, !backup.isEmpty, backup != primary { + hosts.append(backup) + } + + func attempt(_ index: Int) { + if index >= hosts.count { + completion([], 0) + return + } + + let serviceHost = hosts[index] + var components = URLComponents() + components.scheme = "https" + components.host = serviceHost + components.port = servicePort + components.path = "/resolve" + + var queryItems: [URLQueryItem] = [ + URLQueryItem(name: "appId", value: appId), + URLQueryItem(name: "dn", value: hostname), + URLQueryItem(name: "qtype", value: qtype), + URLQueryItem(name: "sdk_version", value: "flutter-ios-1.0.0"), + URLQueryItem(name: "os", value: "ios"), + URLQueryItem(name: "sid", value: sessionId) + ] + + if let secret = secretKey, !secret.isEmpty { + let exp = String(Int(Date().timeIntervalSince1970) + 600) + let nonce = UUID().uuidString.replacingOccurrences(of: "-", with: "") + let signRaw = "\(appId)|\(hostname.lowercased())|\(qtype.uppercased())|\(exp)|\(nonce)" + let sign = hmacSHA256Hex(message: signRaw, secret: secret) + queryItems.append(URLQueryItem(name: "exp", value: exp)) + queryItems.append(URLQueryItem(name: "nonce", value: nonce)) + queryItems.append(URLQueryItem(name: "sign", value: sign)) + } + if let cip = cip, !cip.isEmpty { + queryItems.append(URLQueryItem(name: "cip", value: cip)) + } + + components.queryItems = queryItems + guard let url = components.url else { + completion([], 0) + return + } + + var req = URLRequest(url: url) + req.httpMethod = "GET" + req.timeoutInterval = desiredConnectTimeoutSeconds + desiredReadTimeoutSeconds + req.setValue(serviceHost, forHTTPHeaderField: "Host") + + let config = URLSessionConfiguration.ephemeral + config.timeoutIntervalForRequest = desiredConnectTimeoutSeconds + desiredReadTimeoutSeconds + config.timeoutIntervalForResource = desiredConnectTimeoutSeconds + desiredReadTimeoutSeconds + let session = URLSession(configuration: config) + session.dataTask(with: req) { [weak self] data, _, error in + defer { session.finishTasksAndInvalidate() } + + if let error = error { + if self?.desiredLogEnabled == true { + NSLog("AliyunHttpDns(iOS): resolve request failed host=\(serviceHost), err=\(error.localizedDescription)") + } + attempt(index + 1) + return + } + guard let data = data else { + attempt(index + 1) + return + } + + let parsedIPs = Self.extractIPsFromResolveResponse(data: data, qtype: qtype) + if parsedIPs.isEmpty { + attempt(index + 1) + return + } + let ttl = Self.extractTTLFromResolveResponse(data: data) + completion(parsedIPs, ttl) + }.resume() + } + + attempt(0) + } + + private static func extractIPsFromResolveResponse(data: Data, qtype: String) -> [String] { + guard let obj = try? JSONSerialization.jsonObject(with: data) as? [String: Any], + isResolveSuccessCode(obj["code"]), + let dataObj = obj["data"] as? [String: Any], + let records = dataObj["records"] as? [[String: Any]] else { + return [] + } + + var ips: [String] = [] + for row in records { + let type = ((row["type"] as? String) ?? "").uppercased() + if type != qtype.uppercased() { + continue + } + if let ip = row["ip"] as? String, !ip.isEmpty { + ips.append(ip) + } + } + return ips + } + + private static func extractTTLFromResolveResponse(data: Data) -> Int { + guard let obj = try? JSONSerialization.jsonObject(with: data) as? [String: Any], + let dataObj = obj["data"] as? [String: Any], + let ttlValue = dataObj["ttl"] else { + return 0 + } + if let ttl = ttlValue as? Int { + return ttl + } + if let ttlString = ttlValue as? String, let ttl = Int(ttlString) { + return ttl + } + return 0 + } + + private static func isResolveSuccessCode(_ codeValue: Any?) -> Bool { + if let code = codeValue as? String { + let normalized = code.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() + return normalized == "SUCCESS" || normalized == "0" + } + if let code = codeValue as? Int { + return code == 0 + } + if let code = codeValue as? NSNumber { + return code.intValue == 0 + } + return false + } + + private func hmacSHA256Hex(message: String, secret: String) -> String { + guard let keyData = secret.data(using: .utf8), + let messageData = message.data(using: .utf8) else { + return "" + } + + var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH)) + keyData.withUnsafeBytes { keyBytes in + messageData.withUnsafeBytes { msgBytes in + CCHmac( + CCHmacAlgorithm(kCCHmacAlgSHA256), + keyBytes.baseAddress, + keyData.count, + msgBytes.baseAddress, + messageData.count, + &digest + ) + } + } + return digest.map { String(format: "%02x", $0) }.joined() + } } - - diff --git a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/ios/aliyun_httpdns.podspec b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/ios/aliyun_httpdns.podspec index 6b6371d..11c2b19 100644 --- a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/ios/aliyun_httpdns.podspec +++ b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/ios/aliyun_httpdns.podspec @@ -3,7 +3,7 @@ # Pod::Spec.new do |s| s.name = 'aliyun_httpdns' - s.version = '1.0.2' + s.version = '1.0.0' s.summary = 'aliyun httpdns flutter plugin' s.description = <<-DESC aliyun httpdns flutter plugin. @@ -16,7 +16,6 @@ DESC s.public_header_files = 'Classes/**/*.h' s.static_framework = true s.dependency 'Flutter' - s.dependency 'AlicloudHTTPDNS', '3.4.0' s.platform = :ios, '10.0' # Flutter.framework does not contain a i386 slice. diff --git a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/lib/aliyun_httpdns.dart b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/lib/aliyun_httpdns.dart index 6c04357..bd4070e 100644 --- a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/lib/aliyun_httpdns.dart +++ b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/lib/aliyun_httpdns.dart @@ -1,87 +1,89 @@ -import 'dart:async'; +import 'dart:async'; +import 'dart:io'; +import 'dart:typed_data'; + import 'package:flutter/services.dart'; class AliyunHttpdns { static const MethodChannel _channel = MethodChannel('aliyun_httpdns'); - /// 1) 初始化:使用 accountId/secretKey/aesSecretKey + /// New API only: + /// appId + primary/backup service host + optional sign secret. static Future init({ - required int accountId, + required String appId, + required String primaryServiceHost, + String? backupServiceHost, + int servicePort = 443, String? secretKey, - String? aesSecretKey, }) async { - final ok = - await _channel.invokeMethod('initialize', { - 'accountId': accountId, - if (secretKey != null) 'secretKey': secretKey, - if (aesSecretKey != null) 'aesSecretKey': aesSecretKey, - }); + final String normalizedAppId = appId.trim(); + final String normalizedPrimary = primaryServiceHost.trim(); + if (normalizedAppId.isEmpty || normalizedPrimary.isEmpty) { + return false; + } + + final Map args = { + 'appId': normalizedAppId, + 'primaryServiceHost': normalizedPrimary, + if (backupServiceHost != null && backupServiceHost.trim().isNotEmpty) + 'backupServiceHost': backupServiceHost.trim(), + if (servicePort > 0) 'servicePort': servicePort, + if (secretKey != null && secretKey.isNotEmpty) 'secretKey': secretKey, + }; + + final bool? ok = await _channel.invokeMethod('initialize', args); return ok ?? false; } - /// 构建底层 service,只有在调用了 initialize / 一系列 setXxx 后, - /// 调用本方法才会真正创建底层实例并应用配置 static Future build() async { - final ok = await _channel.invokeMethod('build'); + final bool? ok = await _channel.invokeMethod('build'); return ok ?? false; } - /// 2) 设置日志开关 static Future setLogEnabled(bool enabled) async { - await _channel.invokeMethod('setLogEnabled', { - 'enabled': enabled, - }); + await _channel.invokeMethod('setLogEnabled', {'enabled': enabled}); } - /// 3) 设置持久化缓存 static Future setPersistentCacheIPEnabled(bool enabled, {int? discardExpiredAfterSeconds}) async { - await _channel - .invokeMethod('setPersistentCacheIPEnabled', { + await _channel.invokeMethod('setPersistentCacheIPEnabled', { 'enabled': enabled, if (discardExpiredAfterSeconds != null) 'discardExpiredAfterSeconds': discardExpiredAfterSeconds, }); } - /// 4) 是否允许复用过期 IP static Future setReuseExpiredIPEnabled(bool enabled) async { await _channel - .invokeMethod('setReuseExpiredIPEnabled', { - 'enabled': enabled, - }); + .invokeMethod('setReuseExpiredIPEnabled', {'enabled': enabled}); } - /// 设置是否使用 HTTPS 解析链路,避免明文流量被系统拦截 static Future setHttpsRequestEnabled(bool enabled) async { await _channel - .invokeMethod('setHttpsRequestEnabled', { - 'enabled': enabled, - }); + .invokeMethod('setHttpsRequestEnabled', {'enabled': enabled}); } - /// 5) 伪异步解析:返回 IPv4/IPv6 数组 - /// 返回格式:{"ipv4": `List`, "ipv6": `List`} static Future>> resolveHostSyncNonBlocking( String hostname, { String ipType = 'auto', // auto/ipv4/ipv6/both - Map? sdnsParams, - String? cacheKey, }) async { - final Map? res = await _channel - .invokeMethod('resolveHostSyncNonBlocking', { + final Map? res = + await _channel.invokeMethod>('resolveHostSyncNonBlocking', + { 'hostname': hostname, 'ipType': ipType, - if (sdnsParams != null) 'sdnsParams': sdnsParams, - if (cacheKey != null) 'cacheKey': cacheKey, }); - final Map> out = { + + final Map> out = >{ 'ipv4': [], 'ipv6': [], }; - if (res == null) return out; - final v4 = res['ipv4']; - final v6 = res['ipv6']; + if (res == null) { + return out; + } + + final dynamic v4 = res['ipv4']; + final dynamic v6 = res['ipv6']; if (v4 is List) { out['ipv4'] = v4.map((e) => e.toString()).toList(); } @@ -91,51 +93,190 @@ class AliyunHttpdns { return out; } - // 解析域名,返回 A/AAAA 记录等(保留旧接口以兼容,未在本任务使用) - static Future?> resolve(String hostname, - {Map? options}) async { - final res = await _channel.invokeMethod>('resolve', { + /// V1 resolve API: + /// qtype supports A / AAAA, optional cip for route simulation. + static Future> resolveHost( + String hostname, { + String qtype = 'A', + String? cip, + }) async { + final Map? res = + await _channel.invokeMethod>('resolveHostV1', { 'hostname': hostname, - if (options != null) 'options': options, + 'qtype': qtype, + if (cip != null && cip.trim().isNotEmpty) 'cip': cip.trim(), }); - return res?.map((key, value) => MapEntry(key.toString(), value)); + + final Map out = { + 'ipv4': [], + 'ipv6': [], + 'ttl': 0, + }; + if (res == null) { + return out; + } + final dynamic v4 = res['ipv4']; + final dynamic v6 = res['ipv6']; + if (v4 is List) { + out['ipv4'] = v4.map((e) => e.toString()).toList(); + } + if (v6 is List) { + out['ipv6'] = v6.map((e) => e.toString()).toList(); + } + final dynamic ttl = res['ttl']; + if (ttl is int) { + out['ttl'] = ttl; + } + return out; } - // 1) setPreResolveHosts: 传入 host 列表,native 侧调用 SDK 预解析 - static Future setPreResolveHosts(List hosts, - {String ipType = 'auto'}) async { + static Future setPreResolveHosts(List hosts, {String ipType = 'auto'}) async { await _channel.invokeMethod('setPreResolveHosts', { 'hosts': hosts, 'ipType': ipType, }); } - // 2) setLogEnabled: 已有,同步保留(在此文件顶部已有 setLogEnabled 实现) - - // 3) setPreResolveAfterNetworkChanged: 是否在网络切换时自动刷新解析 static Future setPreResolveAfterNetworkChanged(bool enabled) async { - await _channel.invokeMethod( - 'setPreResolveAfterNetworkChanged', { + await _channel.invokeMethod('setPreResolveAfterNetworkChanged', { 'enabled': enabled, }); } - // 4) getSessionId: 获取会话 id - static Future getSessionId() async { - final sid = await _channel.invokeMethod('getSessionId'); - return sid; + static Future setIPRankingList(Map hostPortMap) async { + await _channel + .invokeMethod('setIPRankingList', {'hostPortMap': hostPortMap}); + } + + static Future getSessionId() async { + return _channel.invokeMethod('getSessionId'); } - // 5) cleanAllHostCache: 清除所有缓存 static Future cleanAllHostCache() async { await _channel.invokeMethod('cleanAllHostCache'); } - - /// 设置 IP 优选列表 - /// [hostPortMap] 域名和端口的映射,例如:{'www.aliyun.com': 443} - static Future setIPRankingList(Map hostPortMap) async { - await _channel.invokeMethod('setIPRankingList', { - 'hostPortMap': hostPortMap, - }); + + static AliyunHttpdnsHttpAdapter createHttpAdapter({ + AliyunHttpdnsAdapterOptions options = const AliyunHttpdnsAdapterOptions(), + }) { + return AliyunHttpdnsHttpAdapter._(options); + } +} + +class AliyunHttpdnsAdapterOptions { + final String ipType; + final int connectTimeoutMs; + final int readTimeoutMs; + final bool allowInsecureCertificatesForDebugOnly; + + const AliyunHttpdnsAdapterOptions({ + this.ipType = 'auto', + this.connectTimeoutMs = 3000, + this.readTimeoutMs = 5000, + this.allowInsecureCertificatesForDebugOnly = false, + }); +} + +class AliyunHttpdnsRequestResult { + final int statusCode; + final Map> headers; + final Uint8List body; + final String usedIp; + + const AliyunHttpdnsRequestResult({ + required this.statusCode, + required this.headers, + required this.body, + required this.usedIp, + }); +} + +class AliyunHttpdnsHttpAdapter { + final AliyunHttpdnsAdapterOptions _options; + + AliyunHttpdnsHttpAdapter._(this._options); + + /// Fixed behavior: + /// 1) resolve host by HTTPDNS + /// 2) connect to IP:443 + /// 3) keep HTTP Host as original domain + /// 4) no fallback to domain connect + Future request( + Uri uri, { + String method = 'GET', + Map? headers, + List? body, + }) async { + if (uri.host.isEmpty) { + throw const HttpException('HOST_ROUTE_REJECTED: host is empty'); + } + if (uri.scheme.toLowerCase() != 'https') { + throw const HttpException('TLS_EMPTY_SNI_FAILED: only https is supported'); + } + + final Map> resolved = await AliyunHttpdns.resolveHostSyncNonBlocking( + uri.host, + ipType: _options.ipType, + ); + final List ips = [ + ...?resolved['ipv4'], + ...?resolved['ipv6'], + ]; + if (ips.isEmpty) { + throw const HttpException('NO_IP_AVAILABLE: HTTPDNS returned empty ip list'); + } + + Object? lastError; + for (final String ip in ips) { + final HttpClient client = HttpClient(); + client.connectionTimeout = Duration(milliseconds: _options.connectTimeoutMs); + if (_options.allowInsecureCertificatesForDebugOnly) { + client.badCertificateCallback = (_, __, ___) => true; + } + + try { + final Uri target = uri.replace( + host: ip, + port: uri.hasPort ? uri.port : 443, + ); + final HttpClientRequest req = await client + .openUrl(method, target) + .timeout(Duration(milliseconds: _options.connectTimeoutMs)); + req.headers.host = uri.host; + headers?.forEach((String key, String value) { + if (key.toLowerCase() == 'host') { + return; + } + req.headers.set(key, value); + }); + if (body != null && body.isNotEmpty) { + req.add(body); + } + + final HttpClientResponse resp = + await req.close().timeout(Duration(milliseconds: _options.readTimeoutMs)); + final List payload = + await resp.fold>([], (List previous, List element) { + previous.addAll(element); + return previous; + }); + final Map> responseHeaders = >{}; + resp.headers.forEach((String name, List values) { + responseHeaders[name] = values; + }); + return AliyunHttpdnsRequestResult( + statusCode: resp.statusCode, + headers: responseHeaders, + body: Uint8List.fromList(payload), + usedIp: ip, + ); + } catch (e) { + lastError = e; + } finally { + client.close(force: true); + } + } + + throw HttpException('TLS_EMPTY_SNI_FAILED: all ip connect attempts failed, error=$lastError'); } } diff --git a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/pubspec.yaml b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/pubspec.yaml index c94d56c..aa781b3 100644 --- a/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/pubspec.yaml +++ b/EdgeHttpDNS/sdk/flutter/aliyun_httpdns/pubspec.yaml @@ -1,6 +1,6 @@ name: aliyun_httpdns description: "Aliyun HTTPDNS Flutter plugin." -version: 1.0.2 +version: 1.0.0 homepage: https://help.aliyun.com/document_detail/2584339.html environment: diff --git a/EdgeHttpDNS/sdk/ios/AlicloudHTTPDNS.podspec b/EdgeHttpDNS/sdk/ios/AlicloudHTTPDNS.podspec index d307de8..9e1bbb2 100644 --- a/EdgeHttpDNS/sdk/ios/AlicloudHTTPDNS.podspec +++ b/EdgeHttpDNS/sdk/ios/AlicloudHTTPDNS.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "AlicloudHTTPDNS" - s.version = "3.4.1" + s.version = "1.0.0" s.summary = "Aliyun Mobile Service HTTPDNS iOS SDK (source distribution)." s.description = <<-DESC HTTPDNS iOS SDK 源码分发版本,提供通过 HTTP(S) 进行域名解析、 @@ -27,6 +27,7 @@ Pod::Spec.new do |s| s.public_header_files = [ "AlicloudHttpDNS/AlicloudHttpDNS.h", "AlicloudHttpDNS/HttpdnsService.h", + "AlicloudHttpDNS/HttpdnsEdgeService.h", "AlicloudHttpDNS/Model/HttpdnsResult.h", "AlicloudHttpDNS/Model/HttpdnsRequest.h", "AlicloudHttpDNS/Log/HttpdnsLog.h", diff --git a/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/AlicloudHttpDNS.h b/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/AlicloudHttpDNS.h index e5f94c4..84c3efd 100644 --- a/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/AlicloudHttpDNS.h +++ b/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/AlicloudHttpDNS.h @@ -24,6 +24,7 @@ #import #import #import +#import #import #import #import diff --git a/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/Config/HttpdnsPublicConstant.h b/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/Config/HttpdnsPublicConstant.h index 0b20389..e7be431 100644 --- a/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/Config/HttpdnsPublicConstant.h +++ b/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/Config/HttpdnsPublicConstant.h @@ -9,7 +9,7 @@ #ifndef PublicConstant_h #define PublicConstant_h -static NSString *const HTTPDNS_IOS_SDK_VERSION = @"3.4.1"; +static NSString *const HTTPDNS_IOS_SDK_VERSION = @"1.0.0"; #define ALICLOUD_HTTPDNS_DEFAULT_REGION_KEY @"cn" #define ALICLOUD_HTTPDNS_HONGKONG_REGION_KEY @"hk" diff --git a/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/HttpdnsEdgeService.h b/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/HttpdnsEdgeService.h new file mode 100644 index 0000000..98a8d57 --- /dev/null +++ b/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/HttpdnsEdgeService.h @@ -0,0 +1,36 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface HttpdnsEdgeResolveResult : NSObject + +@property (nonatomic, copy) NSString *requestId; +@property (nonatomic, copy) NSArray *ipv4s; +@property (nonatomic, copy) NSArray *ipv6s; +@property (nonatomic, assign) NSInteger ttl; + +@end + +@interface HttpdnsEdgeService : NSObject + +- (instancetype)initWithAppId:(NSString *)appId + primaryServiceHost:(NSString *)primaryServiceHost + backupServiceHost:(nullable NSString *)backupServiceHost + servicePort:(NSInteger)servicePort + signSecret:(nullable NSString *)signSecret; + +- (void)resolveHost:(NSString *)host + queryType:(NSString *)queryType + completion:(void (^)(HttpdnsEdgeResolveResult *_Nullable result, NSError *_Nullable error))completion; + +/// Connect by IP + HTTPS and keep Host header as business domain. +/// This path will not fallback to domain connect. +- (void)requestURL:(NSURL *)url + method:(NSString *)method + headers:(nullable NSDictionary *)headers + body:(nullable NSData *)body + completion:(void (^)(NSData *_Nullable data, NSHTTPURLResponse *_Nullable response, NSError *_Nullable error))completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/HttpdnsEdgeService.m b/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/HttpdnsEdgeService.m new file mode 100644 index 0000000..8b8accd --- /dev/null +++ b/EdgeHttpDNS/sdk/ios/AlicloudHttpDNS/HttpdnsEdgeService.m @@ -0,0 +1,277 @@ +#import "HttpdnsEdgeService.h" + +#import + +static NSString * const kHttpdnsEdgeErrorDomain = @"com.goeedge.httpdns.edge"; + +@implementation HttpdnsEdgeResolveResult +@end + +@interface HttpdnsEdgeService () + +@property (nonatomic, copy) NSString *appId; +@property (nonatomic, copy) NSString *primaryServiceHost; +@property (nonatomic, copy) NSString *backupServiceHost; +@property (nonatomic, assign) NSInteger servicePort; +@property (nonatomic, copy) NSString *signSecret; +@property (nonatomic, copy) NSString *sessionId; + +@end + +@implementation HttpdnsEdgeService + +- (instancetype)initWithAppId:(NSString *)appId + primaryServiceHost:(NSString *)primaryServiceHost + backupServiceHost:(NSString *)backupServiceHost + servicePort:(NSInteger)servicePort + signSecret:(NSString *)signSecret { + if (self = [super init]) { + _appId = [appId copy]; + _primaryServiceHost = [primaryServiceHost copy]; + _backupServiceHost = backupServiceHost.length > 0 ? [backupServiceHost copy] : @""; + _servicePort = servicePort > 0 ? servicePort : 443; + _signSecret = signSecret.length > 0 ? [signSecret copy] : @""; + _sessionId = [[[NSUUID UUID].UUIDString stringByReplacingOccurrencesOfString:@"-" withString:@""] copy]; + } + return self; +} + +- (void)resolveHost:(NSString *)host + queryType:(NSString *)queryType + completion:(void (^)(HttpdnsEdgeResolveResult *_Nullable, NSError *_Nullable))completion { + if (host.length == 0 || self.appId.length == 0 || self.primaryServiceHost.length == 0) { + NSError *error = [NSError errorWithDomain:kHttpdnsEdgeErrorDomain + code:1001 + userInfo:@{NSLocalizedDescriptionKey: @"invalid init config or host"}]; + completion(nil, error); + return; + } + + NSString *qtype = queryType.length > 0 ? queryType.uppercaseString : @"A"; + NSArray *hosts = self.backupServiceHost.length > 0 + ? @[self.primaryServiceHost, self.backupServiceHost] + : @[self.primaryServiceHost]; + + [self requestResolveHosts:hosts index:0 host:host qtype:qtype completion:completion]; +} + +- (void)requestURL:(NSURL *)url + method:(NSString *)method + headers:(NSDictionary *)headers + body:(NSData *)body + completion:(void (^)(NSData *_Nullable, NSHTTPURLResponse *_Nullable, NSError *_Nullable))completion { + NSString *originHost = url.host ?: @""; + if (originHost.length == 0) { + NSError *error = [NSError errorWithDomain:kHttpdnsEdgeErrorDomain + code:2001 + userInfo:@{NSLocalizedDescriptionKey: @"invalid request host"}]; + completion(nil, nil, error); + return; + } + + [self resolveHost:originHost queryType:@"A" completion:^(HttpdnsEdgeResolveResult * _Nullable result, NSError * _Nullable error) { + if (error != nil || result.ipv4s.count == 0) { + completion(nil, nil, error ?: [NSError errorWithDomain:kHttpdnsEdgeErrorDomain + code:2002 + userInfo:@{NSLocalizedDescriptionKey: @"NO_IP_AVAILABLE"}]); + return; + } + + [self requestByIPList:result.ipv4s + index:0 + url:url + method:method + headers:headers + body:body + completion:completion]; + }]; +} + +- (void)requestByIPList:(NSArray *)ips + index:(NSInteger)index + url:(NSURL *)url + method:(NSString *)method + headers:(NSDictionary *)headers + body:(NSData *)body + completion:(void (^)(NSData *_Nullable, NSHTTPURLResponse *_Nullable, NSError *_Nullable))completion { + if (index >= ips.count) { + NSError *error = [NSError errorWithDomain:kHttpdnsEdgeErrorDomain + code:2003 + userInfo:@{NSLocalizedDescriptionKey: @"TLS_EMPTY_SNI_FAILED"}]; + completion(nil, nil, error); + return; + } + + NSString *ip = ips[index]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; + components.host = ip; + if (components.port == nil) { + components.port = @(443); + } + + NSURL *targetURL = components.URL; + if (targetURL == nil) { + [self requestByIPList:ips index:index + 1 url:url method:method headers:headers body:body completion:completion]; + return; + } + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:targetURL + cachePolicy:NSURLRequestReloadIgnoringLocalCacheData + timeoutInterval:8]; + request.HTTPMethod = method.length > 0 ? method : @"GET"; + if (body.length > 0) { + request.HTTPBody = body; + } + + [request setValue:url.host forHTTPHeaderField:@"Host"]; + [headers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + if ([key.lowercaseString isEqualToString:@"host"]) { + return; + } + [request setValue:obj forHTTPHeaderField:key]; + }]; + + NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + config.timeoutIntervalForRequest = 8; + config.timeoutIntervalForResource = 8; + NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; + + [[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + [session finishTasksAndInvalidate]; + + if (error != nil) { + [self requestByIPList:ips index:index + 1 url:url method:method headers:headers body:body completion:completion]; + return; + } + + completion(data, (NSHTTPURLResponse *)response, nil); + }] resume]; +} + +- (void)requestResolveHosts:(NSArray *)hosts + index:(NSInteger)index + host:(NSString *)host + qtype:(NSString *)qtype + completion:(void (^)(HttpdnsEdgeResolveResult *_Nullable result, NSError *_Nullable error))completion { + if (index >= hosts.count) { + NSError *error = [NSError errorWithDomain:kHttpdnsEdgeErrorDomain + code:1002 + userInfo:@{NSLocalizedDescriptionKey: @"resolve failed on all service hosts"}]; + completion(nil, error); + return; + } + + NSString *serviceHost = hosts[index]; + NSURLComponents *components = [NSURLComponents new]; + components.scheme = @"https"; + components.host = serviceHost; + components.port = @(self.servicePort); + components.path = @"/resolve"; + + NSMutableArray *items = [NSMutableArray arrayWithArray:@[ + [NSURLQueryItem queryItemWithName:@"appId" value:self.appId], + [NSURLQueryItem queryItemWithName:@"dn" value:host], + [NSURLQueryItem queryItemWithName:@"qtype" value:qtype], + [NSURLQueryItem queryItemWithName:@"sid" value:self.sessionId], + [NSURLQueryItem queryItemWithName:@"sdk_version" value:@"ios-native-1.0.0"], + [NSURLQueryItem queryItemWithName:@"os" value:@"ios"], + ]]; + + if (self.signSecret.length > 0) { + NSString *exp = [NSString stringWithFormat:@"%ld", (long)([[NSDate date] timeIntervalSince1970] + 600)]; + NSString *nonce = [[NSUUID UUID].UUIDString stringByReplacingOccurrencesOfString:@"-" withString:@""]; + NSString *raw = [NSString stringWithFormat:@"%@|%@|%@|%@|%@", + self.appId, + host.lowercaseString, + qtype.uppercaseString, + exp, + nonce]; + NSString *sign = [self hmacSha256Hex:raw secret:self.signSecret]; + [items addObject:[NSURLQueryItem queryItemWithName:@"exp" value:exp]]; + [items addObject:[NSURLQueryItem queryItemWithName:@"nonce" value:nonce]]; + [items addObject:[NSURLQueryItem queryItemWithName:@"sign" value:sign]]; + } + + components.queryItems = items; + NSURL *url = components.URL; + if (url == nil) { + [self requestResolveHosts:hosts index:index + 1 host:host qtype:qtype completion:completion]; + return; + } + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url + cachePolicy:NSURLRequestReloadIgnoringLocalCacheData + timeoutInterval:6]; + request.HTTPMethod = @"GET"; + + NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + config.timeoutIntervalForRequest = 6; + config.timeoutIntervalForResource = 6; + NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; + + [[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + [session finishTasksAndInvalidate]; + + if (error != nil || data.length == 0) { + [self requestResolveHosts:hosts index:index + 1 host:host qtype:qtype completion:completion]; + return; + } + + NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; + if (![json isKindOfClass:NSDictionary.class]) { + [self requestResolveHosts:hosts index:index + 1 host:host qtype:qtype completion:completion]; + return; + } + + NSString *code = [NSString stringWithFormat:@"%@", json[@"code"] ?: @""]; + if (![code.uppercaseString isEqualToString:@"SUCCESS"]) { + [self requestResolveHosts:hosts index:index + 1 host:host qtype:qtype completion:completion]; + return; + } + + NSDictionary *dataJSON = [json[@"data"] isKindOfClass:NSDictionary.class] ? json[@"data"] : @{}; + NSArray *records = [dataJSON[@"records"] isKindOfClass:NSArray.class] ? dataJSON[@"records"] : @[]; + + NSMutableArray *ipv4 = [NSMutableArray array]; + NSMutableArray *ipv6 = [NSMutableArray array]; + for (NSDictionary *row in records) { + NSString *type = [NSString stringWithFormat:@"%@", row[@"type"] ?: @""]; + NSString *ip = [NSString stringWithFormat:@"%@", row[@"ip"] ?: @""]; + if (ip.length == 0) { + continue; + } + if ([type.uppercaseString isEqualToString:@"AAAA"]) { + [ipv6 addObject:ip]; + } else { + [ipv4 addObject:ip]; + } + } + + HttpdnsEdgeResolveResult *result = [HttpdnsEdgeResolveResult new]; + result.requestId = [NSString stringWithFormat:@"%@", json[@"requestId"] ?: @""]; + result.ipv4s = ipv4; + result.ipv6s = ipv6; + result.ttl = [dataJSON[@"ttl"] integerValue]; + completion(result, nil); + }] resume]; +} + +- (NSString *)hmacSha256Hex:(NSString *)data secret:(NSString *)secret { + NSData *keyData = [secret dataUsingEncoding:NSUTF8StringEncoding]; + NSData *messageData = [data dataUsingEncoding:NSUTF8StringEncoding]; + unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; + CCHmac(kCCHmacAlgSHA256, + keyData.bytes, + keyData.length, + messageData.bytes, + messageData.length, + cHMAC); + + NSMutableString *result = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; + for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) { + [result appendFormat:@"%02x", cHMAC[i]]; + } + return result; +} + +@end diff --git a/EdgeHttpDNS/sdk/ios/README.md b/EdgeHttpDNS/sdk/ios/README.md index 6853d4d..801c69a 100644 --- a/EdgeHttpDNS/sdk/ios/README.md +++ b/EdgeHttpDNS/sdk/ios/README.md @@ -1,73 +1,58 @@ -# Alicloud HTTPDNS iOS SDK +# HTTPDNS iOS SDK (SNI Hidden v1.0.0) -面向 iOS 的 HTTP/HTTPS DNS 解析 SDK,提供鉴权与可选 AES 加密、IPv4/IPv6 双栈解析、缓存与调度、预解析等能力。最低支持 iOS 12.0。 +## 1. Init -## 功能特性 -- 鉴权请求与可选 AES 传输加密 -- IPv4/IPv6 双栈解析,支持自动/同时解析 -- 内存 + 持久化缓存与 TTL 控制,可选择复用过期 IP -- 预解析、区域路由、网络切换自动刷新 -- 可定制日志回调与会话追踪 `sessionId` - -## 安装(CocoaPods) -在 `Podfile` 中添加: - -```ruby -platform :ios, '12.0' -target 'YourApp' do - pod 'AlicloudHTTPDNS', '~> 3.4.1' -end -``` - -执行 `pod install` 安装依赖。 - -## 快速开始 -Objective‑C ```objc -#import +#import -// 使用鉴权初始化(单例);密钥请勿硬编码到仓库 -HttpDnsService *service = [[HttpDnsService alloc] initWithAccountID:1000000 - secretKey:@""]; -[service setPersistentCacheIPEnabled:YES]; -[service setPreResolveHosts:@[@"www.aliyun.com"] byIPType:HttpdnsQueryIPTypeAuto]; - -// 同步解析(会根据网络自动选择 v4/v6) -HttpdnsResult *r = [service resolveHostSync:@"www.aliyun.com" byIpType:HttpdnsQueryIPTypeAuto]; -NSLog(@"IPv4: %@", r.ips); +HttpdnsEdgeService *service = [[HttpdnsEdgeService alloc] + initWithAppId:@"app1f1ndpo9" +primaryServiceHost:@"httpdns-a.example.com" + backupServiceHost:@"httpdns-b.example.com" + servicePort:443 + signSecret:@"your-sign-secret"]; // optional if sign is enabled ``` -Swift -```swift -import AlicloudHttpDNS +## 2. Resolve -_ = HttpDnsService(accountID: 1000000, secretKey: "") -let svc = HttpDnsService.sharedInstance() -let res = svc?.resolveHostSync("www.aliyun.com", byIpType: .auto) -print(res?.ips ?? []) +```objc +[service resolveHost:@"api.business.com" queryType:@"A" completion:^(HttpdnsEdgeResolveResult * _Nullable result, NSError * _Nullable error) { + if (error != nil) { + return; + } + NSLog(@"requestId=%@ ipv4=%@ ipv6=%@ ttl=%ld", result.requestId, result.ipv4s, result.ipv6s, (long)result.ttl); +}]; ``` -提示 -- 启动时通过 `setPreResolveHosts(_:byIPType:)` 预热热点域名。 -- 如需在刷新期间容忍 TTL 过期,可开启 `setReuseExpiredIPEnabled:YES`。 -- 使用 `getSessionId()` 并与选用 IP 一同记录,便于排障。 +## 3. Official Request Adapter (IP + Host) -## 源码构建 -执行 `./build_xc_framework.sh` 生成 XCFramework。脚本会从 `gitlab.alibaba-inc.com` 克隆内部构建工具;外部环境建议优先使用 CocoaPods 引入。 +```objc +NSURL *url = [NSURL URLWithString:@"https://api.business.com/v1/ping"]; +[service requestURL:url method:@"GET" headers:@{@"Accept": @"application/json"} body:nil completion:^(NSData * _Nullable data, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error) { + if (error != nil) { + return; + } + NSLog(@"status=%ld", (long)response.statusCode); +}]; +``` -## 测试 -- 在 Xcode 使用 Scheme `AlicloudHttpDNSTests` 运行。 -- 含 OCMock 的用例批量执行可能出现内存问题,请单个运行。 -- 非 Mock 用例使用预置参数:AccountID `1000000`,测试域名 `*.onlyforhttpdnstest.run.place`(每年需续期)。 +Behavior is fixed: +- Resolve by `/resolve`. +- Connect to resolved IP over HTTPS. +- Keep `Host` header as business domain. +- No fallback to domain direct request. -## 依赖与链接 -- iOS 12.0+;需链接 `CoreTelephony`、`SystemConfiguration` -- 额外库:`sqlite3.0`、`resolv`;`OTHER_LDFLAGS` 包含 `-ObjC -lz` +## 4. Public Errors -## 安全说明 -- 切勿提交真实的 AccountID/SecretKey,請通过本地安全配置或 CI 注入。 -- 若担心设备时间偏差影响鉴权,可用 `setInternalAuthTimeBaseBySpecifyingCurrentTime:` 校正。 +- `NO_IP_AVAILABLE` +- `TLS_EMPTY_SNI_FAILED` +- `HOST_ROUTE_REJECTED` +- `RESOLVE_SIGN_INVALID` -## Demo 与贡献 -- 示例应用:`AlicloudHttpDNSTestDemo/` -- 贡献与提交流程请参见 `AGENTS.md`(提交信息与 PR 规范)。 +## 5. Removed Public Params + +Do not expose legacy public parameters: +- `accountId` +- `serviceDomain` +- `endpoint` +- `aesSecretKey` diff --git a/EdgeNode/internal/const/const.go b/EdgeNode/internal/const/const.go index 73081fb..49184b0 100644 --- a/EdgeNode/internal/const/const.go +++ b/EdgeNode/internal/const/const.go @@ -1,7 +1,7 @@ package teaconst const ( - Version = "1.4.7" //1.3.8.2 + Version = "1.4.8" //1.3.8.2 ProductName = "Edge Node" ProcessName = "edge-node" diff --git a/deploy/clickhouse/init_waf_logs_tables.sh b/deploy/clickhouse/init_waf_logs_tables.sh index 0f524cc..41d7f10 100644 --- a/deploy/clickhouse/init_waf_logs_tables.sh +++ b/deploy/clickhouse/init_waf_logs_tables.sh @@ -33,6 +33,6 @@ clickhouse-client "${args[@]}" --database "${CH_DATABASE}" < "${SQL_FILE}" echo "[INFO] checking table status ..." clickhouse-client "${args[@]}" --database "${CH_DATABASE}" --query \ - "SELECT name, engine FROM system.tables WHERE database='${CH_DATABASE}' AND name IN ('logs_ingest','dns_logs_ingest') ORDER BY name" + "SELECT name, engine FROM system.tables WHERE database='${CH_DATABASE}' AND name IN ('logs_ingest','dns_logs_ingest','httpdns_access_logs_ingest') ORDER BY name" echo "[OK] ClickHouse ingest tables are ready in database '${CH_DATABASE}'" diff --git a/deploy/clickhouse/init_waf_logs_tables.sql b/deploy/clickhouse/init_waf_logs_tables.sql index 239e024..f4e98e8 100644 --- a/deploy/clickhouse/init_waf_logs_tables.sql +++ b/deploy/clickhouse/init_waf_logs_tables.sql @@ -67,3 +67,36 @@ ENGINE = MergeTree PARTITION BY toYYYYMMDD(timestamp) ORDER BY (timestamp, request_id, node_id) SETTINGS index_granularity = 8192; + +CREATE TABLE IF NOT EXISTS httpdns_access_logs_ingest +( + request_id String, + cluster_id UInt64, + node_id UInt64, + app_id String, + app_name String, + domain String, + qtype LowCardinality(String), + client_ip String, + client_region String, + carrier String, + sdk_version String, + os LowCardinality(String), + result_ips String, + status LowCardinality(String), + error_code String, + cost_ms UInt32, + created_at UInt64, + day String, + summary String CODEC(ZSTD(1)), + INDEX idx_request_id request_id TYPE bloom_filter(0.01) GRANULARITY 4, + INDEX idx_cluster_id cluster_id TYPE minmax GRANULARITY 4, + INDEX idx_node_id node_id TYPE minmax GRANULARITY 4, + INDEX idx_app_id app_id TYPE tokenbf_v1(10240, 3, 0) GRANULARITY 4, + INDEX idx_domain domain TYPE tokenbf_v1(10240, 3, 0) GRANULARITY 4, + INDEX idx_status status TYPE minmax GRANULARITY 4 +) +ENGINE = MergeTree +PARTITION BY day +ORDER BY (day, created_at, request_id, node_id) +SETTINGS index_granularity = 8192; diff --git a/httpdns_app_model.o b/httpdns_app_model.o new file mode 100644 index 0000000..8a089cb Binary files /dev/null and b/httpdns_app_model.o differ