换成单集群模式
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package apps
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -57,24 +57,61 @@ func (this *AppSettingsAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
clusterDomainMap := map[int64]string{}
|
||||
clusterApiAddressMap := map[int64]string{}
|
||||
clusterNameMap := map[int64]string{}
|
||||
for _, cluster := range clusterResp.GetClusters() {
|
||||
clusterDomainMap[cluster.GetId()] = cluster.GetServiceDomain()
|
||||
port := "443"
|
||||
if rawTLS := cluster.GetTlsPolicyJSON(); len(rawTLS) > 0 {
|
||||
var tlsConfig map[string]interface{}
|
||||
if err := json.Unmarshal(rawTLS, &tlsConfig); err == nil {
|
||||
if listenRaw, ok := tlsConfig["listen"]; ok && listenRaw != nil {
|
||||
if data, err := json.Marshal(listenRaw); err == nil {
|
||||
var listenAddresses []map[string]interface{}
|
||||
if err := json.Unmarshal(data, &listenAddresses); err == nil {
|
||||
if len(listenAddresses) > 0 {
|
||||
if portRange, ok := listenAddresses[0]["portRange"].(string); ok && len(portRange) > 0 {
|
||||
port = portRange
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
apiAddress := "https://" + cluster.GetServiceDomain() + ":" + port
|
||||
clusterApiAddressMap[cluster.GetId()] = apiAddress
|
||||
clusterNameMap[cluster.GetId()] = cluster.GetName()
|
||||
}
|
||||
|
||||
// 读取应用绑定的集群列表
|
||||
var clusterIds []int64
|
||||
if raw := app.Get("clusterIds"); raw != nil {
|
||||
if ids, ok := raw.([]int64); ok {
|
||||
clusterIds = ids
|
||||
}
|
||||
}
|
||||
|
||||
// 构建服务地址列表
|
||||
serviceAddresses := make([]maps.Map, 0)
|
||||
for _, cid := range clusterIds {
|
||||
addr := clusterApiAddressMap[cid]
|
||||
name := clusterNameMap[cid]
|
||||
if len(addr) > 0 {
|
||||
serviceAddresses = append(serviceAddresses, maps.Map{
|
||||
"address": addr,
|
||||
"clusterName": name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
primaryClusterId := app.GetInt64("primaryClusterId")
|
||||
backupClusterId := app.GetInt64("backupClusterId")
|
||||
settings := maps.Map{
|
||||
"appId": app.GetString("appId"),
|
||||
"appStatus": app.GetBool("isOn"),
|
||||
"primaryClusterId": primaryClusterId,
|
||||
"backupClusterId": backupClusterId,
|
||||
"primaryServiceDomain": clusterDomainMap[primaryClusterId],
|
||||
"backupServiceDomain": clusterDomainMap[backupClusterId],
|
||||
"signEnabled": app.GetBool("signEnabled"),
|
||||
"signSecretPlain": app.GetString("signSecretPlain"),
|
||||
"signSecretMasked": app.GetString("signSecretMasked"),
|
||||
"signSecretUpdatedAt": app.GetString("signSecretUpdated"),
|
||||
"appId": app.GetString("appId"),
|
||||
"appStatus": app.GetBool("isOn"),
|
||||
"serviceAddresses": serviceAddresses,
|
||||
"signEnabled": app.GetBool("signEnabled"),
|
||||
"signSecretPlain": app.GetString("signSecretPlain"),
|
||||
"signSecretMasked": app.GetString("signSecretMasked"),
|
||||
"signSecretUpdatedAt": app.GetString("signSecretUpdated"),
|
||||
}
|
||||
this.Data["app"] = app
|
||||
this.Data["settings"] = settings
|
||||
@@ -104,12 +141,11 @@ func (this *AppSettingsAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
_, err = this.RPC().HTTPDNSAppRPC().UpdateHTTPDNSApp(this.UserContext(), &pb.UpdateHTTPDNSAppRequest{
|
||||
AppDbId: params.AppId,
|
||||
Name: appResp.GetApp().GetName(),
|
||||
PrimaryClusterId: appResp.GetApp().GetPrimaryClusterId(),
|
||||
BackupClusterId: appResp.GetApp().GetBackupClusterId(),
|
||||
IsOn: params.AppStatus,
|
||||
UserId: appResp.GetApp().GetUserId(),
|
||||
AppDbId: params.AppId,
|
||||
Name: appResp.GetApp().GetName(),
|
||||
ClusterIdsJSON: appResp.GetApp().GetClusterIdsJSON(),
|
||||
IsOn: params.AppStatus,
|
||||
UserId: appResp.GetApp().GetUserId(),
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -15,7 +15,7 @@ func (this *AppSettingsResetSignSecretAction) RunPost(params struct {
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
params.Must.Field("appId", params.AppId).Gt(0, "璇烽€夋嫨搴旂敤")
|
||||
params.Must.Field("appId", params.AppId).Gt(0, "请选择应用")
|
||||
|
||||
_, err := this.RPC().HTTPDNSAppRPC().ResetHTTPDNSAppSignSecret(this.UserContext(), &pb.ResetHTTPDNSAppSignSecretRequest{
|
||||
AppDbId: params.AppId,
|
||||
|
||||
@@ -16,7 +16,7 @@ func (this *AppSettingsToggleSignEnabledAction) RunPost(params struct {
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
params.Must.Field("appId", params.AppId).Gt(0, "璇烽€夋嫨搴旂敤")
|
||||
params.Must.Field("appId", params.AppId).Gt(0, "请选择应用")
|
||||
|
||||
_, err := this.RPC().HTTPDNSAppRPC().UpdateHTTPDNSAppSignEnabled(this.UserContext(), &pb.UpdateHTTPDNSAppSignEnabledRequest{
|
||||
AppDbId: params.AppId,
|
||||
|
||||
@@ -30,12 +30,10 @@ func (this *CreateAction) RunPost(params struct {
|
||||
params.Must.Field("name", params.Name).Require("请输入应用名称")
|
||||
|
||||
createResp, err := this.RPC().HTTPDNSAppRPC().CreateHTTPDNSApp(this.UserContext(), &pb.CreateHTTPDNSAppRequest{
|
||||
Name: params.Name,
|
||||
AppId: "app" + strconv.FormatInt(time.Now().UnixNano()%1_000_000_000_000, 36),
|
||||
PrimaryClusterId: 0,
|
||||
BackupClusterId: 0,
|
||||
IsOn: true,
|
||||
SignEnabled: true,
|
||||
Name: params.Name,
|
||||
AppId: "app" + strconv.FormatInt(time.Now().UnixNano()%1_000_000_000_000, 36),
|
||||
IsOn: true,
|
||||
SignEnabled: true,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -41,14 +41,14 @@ func (this *CustomRecordsCreatePopupAction) RunGet(params struct {
|
||||
"id": int64(0),
|
||||
"domain": domain.GetString("name"),
|
||||
"lineScope": "china",
|
||||
"lineCarrier": "榛樿",
|
||||
"lineRegion": "榛樿",
|
||||
"lineProvince": "榛樿",
|
||||
"lineContinent": "榛樿",
|
||||
"lineCountry": "榛樿",
|
||||
"lineCarrier": "默认",
|
||||
"lineRegion": "默认",
|
||||
"lineProvince": "默认",
|
||||
"lineContinent": "默认",
|
||||
"lineCountry": "默认",
|
||||
"ruleName": "",
|
||||
"weightEnabled": false,
|
||||
"ttl": 30,
|
||||
"ttl": 60,
|
||||
"isOn": true,
|
||||
"recordItemsJson": `[{"type":"A","value":"","weight":100}]`,
|
||||
}
|
||||
@@ -110,7 +110,7 @@ func (this *CustomRecordsCreatePopupAction) RunPost(params struct {
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
params.Must.Field("appId", params.AppId).Gt(0, "璇烽€夋嫨搴旂敤")
|
||||
params.Must.Field("appId", params.AppId).Gt(0, "请选择应用")
|
||||
params.Must.Field("domainId", params.DomainId).Gt(0, "请选择所属域名")
|
||||
|
||||
params.LineScope = strings.ToLower(strings.TrimSpace(params.LineScope))
|
||||
@@ -147,19 +147,19 @@ func (this *CustomRecordsCreatePopupAction) RunPost(params struct {
|
||||
lineContinent := strings.TrimSpace(params.LineContinent)
|
||||
lineCountry := strings.TrimSpace(params.LineCountry)
|
||||
if len(lineCarrier) == 0 {
|
||||
lineCarrier = "榛樿"
|
||||
lineCarrier = "默认"
|
||||
}
|
||||
if len(lineRegion) == 0 {
|
||||
lineRegion = "榛樿"
|
||||
lineRegion = "默认"
|
||||
}
|
||||
if len(lineProvince) == 0 {
|
||||
lineProvince = "榛樿"
|
||||
lineProvince = "默认"
|
||||
}
|
||||
if len(lineContinent) == 0 {
|
||||
lineContinent = "榛樿"
|
||||
lineContinent = "默认"
|
||||
}
|
||||
if len(lineCountry) == 0 {
|
||||
lineCountry = "榛樿"
|
||||
lineCountry = "默认"
|
||||
}
|
||||
if params.LineScope == "overseas" {
|
||||
lineCarrier = ""
|
||||
@@ -242,7 +242,7 @@ func parseRecordItemsJSON(raw string, weightEnabled bool) ([]maps.Map, error) {
|
||||
weight = 100
|
||||
}
|
||||
if weight < 1 || weight > 100 {
|
||||
return nil, fmt.Errorf("鏉冮噸鍊煎繀椤诲湪 1-100 涔嬮棿")
|
||||
return nil, fmt.Errorf("权重值必须在 1-100 之间")
|
||||
}
|
||||
|
||||
result = append(result, maps.Map{
|
||||
|
||||
@@ -23,7 +23,6 @@ func (this *DomainsAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
// 鏋勫缓椤堕儴 tabbar
|
||||
httpdnsutils.AddAppTabbar(this.Parent(), app.GetString("name"), params.AppId, "domains")
|
||||
|
||||
domains, err := listDomainMaps(this.Parent(), app.GetInt64("id"), "")
|
||||
|
||||
@@ -32,7 +32,7 @@ func (this *DomainsCreatePopupAction) RunPost(params struct {
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
params.Must.Field("appId", params.AppId).Gt(0, "璇烽€夋嫨搴旂敤")
|
||||
params.Must.Field("appId", params.AppId).Gt(0, "请选择应用")
|
||||
params.Must.Field("domain", params.Domain).Require("请输入域名")
|
||||
|
||||
err := createDomain(this.Parent(), params.AppId, params.Domain)
|
||||
|
||||
@@ -47,13 +47,13 @@ func buildLineText(record maps.Map) string {
|
||||
|
||||
finalParts := make([]string, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
if len(part) == 0 || part == "榛樿" {
|
||||
if len(part) == 0 || part == "默认" {
|
||||
continue
|
||||
}
|
||||
finalParts = append(finalParts, part)
|
||||
}
|
||||
if len(finalParts) == 0 {
|
||||
return "榛樿"
|
||||
return "默认"
|
||||
}
|
||||
return strings.Join(finalParts, " / ")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package apps
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -72,15 +73,14 @@ func findAppMap(parent *actionutils.ParentAction, appDbId int64) (maps.Map, erro
|
||||
return apps[0], nil
|
||||
}
|
||||
|
||||
func createApp(parent *actionutils.ParentAction, name string, primaryClusterId int64, backupClusterId int64) (int64, error) {
|
||||
func createApp(parent *actionutils.ParentAction, name string, clusterIdsJSON []byte) (int64, error) {
|
||||
newAppId := "app" + strconv.FormatInt(time.Now().UnixNano()%1_000_000_000_000, 36)
|
||||
resp, err := parent.RPC().HTTPDNSAppRPC().CreateHTTPDNSApp(parent.UserContext(), &pb.CreateHTTPDNSAppRequest{
|
||||
Name: strings.TrimSpace(name),
|
||||
AppId: newAppId,
|
||||
PrimaryClusterId: primaryClusterId,
|
||||
BackupClusterId: backupClusterId,
|
||||
IsOn: true,
|
||||
SignEnabled: true,
|
||||
Name: strings.TrimSpace(name),
|
||||
AppId: newAppId,
|
||||
ClusterIdsJSON: clusterIdsJSON,
|
||||
IsOn: true,
|
||||
SignEnabled: true,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -95,14 +95,13 @@ func deleteAppByID(parent *actionutils.ParentAction, appDbId int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func updateAppSettings(parent *actionutils.ParentAction, appDbId int64, name string, primaryClusterId int64, backupClusterId int64, isOn bool, userId int64) error {
|
||||
func updateAppSettings(parent *actionutils.ParentAction, appDbId int64, name string, clusterIdsJSON []byte, isOn bool, userId int64) error {
|
||||
_, err := parent.RPC().HTTPDNSAppRPC().UpdateHTTPDNSApp(parent.UserContext(), &pb.UpdateHTTPDNSAppRequest{
|
||||
AppDbId: appDbId,
|
||||
Name: strings.TrimSpace(name),
|
||||
PrimaryClusterId: primaryClusterId,
|
||||
BackupClusterId: backupClusterId,
|
||||
IsOn: isOn,
|
||||
UserId: userId,
|
||||
AppDbId: appDbId,
|
||||
Name: strings.TrimSpace(name),
|
||||
ClusterIdsJSON: clusterIdsJSON,
|
||||
IsOn: isOn,
|
||||
UserId: userId,
|
||||
})
|
||||
return err
|
||||
}
|
||||
@@ -264,17 +263,22 @@ func toggleCustomRule(parent *actionutils.ParentAction, ruleId int64, isOn bool)
|
||||
|
||||
func appPBToMap(app *pb.HTTPDNSApp, domainCount int64) maps.Map {
|
||||
signSecret := app.GetSignSecret()
|
||||
|
||||
// 读取集群 ID 列表
|
||||
var clusterIds []int64
|
||||
if len(app.GetClusterIdsJSON()) > 0 {
|
||||
_ = json.Unmarshal(app.GetClusterIdsJSON(), &clusterIds)
|
||||
}
|
||||
|
||||
return maps.Map{
|
||||
"id": app.GetId(),
|
||||
"name": app.GetName(),
|
||||
"appId": app.GetAppId(),
|
||||
"clusterId": app.GetPrimaryClusterId(),
|
||||
"primaryClusterId": app.GetPrimaryClusterId(),
|
||||
"backupClusterId": app.GetBackupClusterId(),
|
||||
"clusterIds": clusterIds,
|
||||
"userId": app.GetUserId(),
|
||||
"isOn": app.GetIsOn(),
|
||||
"domainCount": domainCount,
|
||||
"sniPolicyText": "闅愬尶 SNI",
|
||||
"sniPolicyText": "隐匿 SNI",
|
||||
"signEnabled": app.GetSignEnabled(),
|
||||
"signSecretPlain": signSecret,
|
||||
"signSecretMasked": maskSecret(signSecret),
|
||||
@@ -285,7 +289,7 @@ func appPBToMap(app *pb.HTTPDNSApp, domainCount int64) maps.Map {
|
||||
func defaultLineField(value string) string {
|
||||
value = strings.TrimSpace(value)
|
||||
if len(value) == 0 {
|
||||
return "榛樿"
|
||||
return "默认"
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package resolveLogs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -45,8 +46,29 @@ func (this *IndexAction) RunGet(params struct {
|
||||
clusterDomainMap := map[int64]string{}
|
||||
for _, cluster := range clusterResp.GetClusters() {
|
||||
serviceDomain := strings.TrimSpace(cluster.GetServiceDomain())
|
||||
displayName := serviceDomain
|
||||
if len(displayName) == 0 {
|
||||
|
||||
port := "443"
|
||||
if rawTLS := cluster.GetTlsPolicyJSON(); len(rawTLS) > 0 {
|
||||
var tlsConfig map[string]interface{}
|
||||
if err := json.Unmarshal(rawTLS, &tlsConfig); err == nil {
|
||||
if listenRaw, ok := tlsConfig["listen"]; ok && listenRaw != nil {
|
||||
if data, err := json.Marshal(listenRaw); err == nil {
|
||||
var listenAddresses []map[string]interface{}
|
||||
if err := json.Unmarshal(data, &listenAddresses); err == nil {
|
||||
if len(listenAddresses) > 0 {
|
||||
if portRange, ok := listenAddresses[0]["portRange"].(string); ok && len(portRange) > 0 {
|
||||
port = portRange
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
apiAddress := "https://" + serviceDomain + ":" + port
|
||||
|
||||
displayName := apiAddress
|
||||
if len(serviceDomain) == 0 {
|
||||
displayName = cluster.GetName()
|
||||
}
|
||||
|
||||
@@ -56,7 +78,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"serviceDomain": serviceDomain,
|
||||
"displayName": displayName,
|
||||
})
|
||||
clusterDomainMap[cluster.GetId()] = serviceDomain
|
||||
clusterDomainMap[cluster.GetId()] = apiAddress
|
||||
}
|
||||
this.Data["clusters"] = clusters
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package sandbox
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -28,8 +29,29 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
clusters := make([]maps.Map, 0, len(clusterResp.GetClusters()))
|
||||
for _, cluster := range clusterResp.GetClusters() {
|
||||
serviceDomain := strings.TrimSpace(cluster.GetServiceDomain())
|
||||
displayName := serviceDomain
|
||||
if len(displayName) == 0 {
|
||||
|
||||
port := "443"
|
||||
if rawTLS := cluster.GetTlsPolicyJSON(); len(rawTLS) > 0 {
|
||||
var tlsConfig map[string]interface{}
|
||||
if err := json.Unmarshal(rawTLS, &tlsConfig); err == nil {
|
||||
if listenRaw, ok := tlsConfig["listen"]; ok && listenRaw != nil {
|
||||
if data, err := json.Marshal(listenRaw); err == nil {
|
||||
var listenAddresses []map[string]interface{}
|
||||
if err := json.Unmarshal(data, &listenAddresses); err == nil {
|
||||
if len(listenAddresses) > 0 {
|
||||
if portRange, ok := listenAddresses[0]["portRange"].(string); ok && len(portRange) > 0 {
|
||||
port = portRange
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
apiAddress := "https://" + serviceDomain + ":" + port
|
||||
|
||||
displayName := apiAddress
|
||||
if len(serviceDomain) == 0 {
|
||||
displayName = cluster.GetName()
|
||||
}
|
||||
clusters = append(clusters, maps.Map{
|
||||
@@ -59,14 +81,18 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
for _, domain := range domainResp.GetDomains() {
|
||||
domains = append(domains, domain.GetDomain())
|
||||
}
|
||||
// 解析集群ID列表
|
||||
var clusterIds []int64
|
||||
if len(app.GetClusterIdsJSON()) > 0 {
|
||||
_ = json.Unmarshal(app.GetClusterIdsJSON(), &clusterIds)
|
||||
}
|
||||
|
||||
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,
|
||||
"id": app.GetId(),
|
||||
"name": app.GetName(),
|
||||
"appId": app.GetAppId(),
|
||||
"clusterIds": clusterIds,
|
||||
"domains": domains,
|
||||
})
|
||||
}
|
||||
this.Data["apps"] = apps
|
||||
|
||||
@@ -3,6 +3,7 @@ package sandbox
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"encoding/hex"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -52,12 +53,30 @@ func (this *TestAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
clusterDomain := ""
|
||||
port := "443"
|
||||
if params.ClusterId > 0 {
|
||||
clusterResp, findErr := this.RPC().HTTPDNSClusterRPC().FindAllHTTPDNSClusters(this.UserContext(), &pb.FindAllHTTPDNSClustersRequest{})
|
||||
if findErr == nil {
|
||||
for _, cluster := range clusterResp.GetClusters() {
|
||||
if cluster.GetId() == params.ClusterId {
|
||||
clusterDomain = strings.TrimSpace(cluster.GetServiceDomain())
|
||||
if rawTLS := cluster.GetTlsPolicyJSON(); len(rawTLS) > 0 {
|
||||
var tlsConfig map[string]interface{}
|
||||
if err := json.Unmarshal(rawTLS, &tlsConfig); err == nil {
|
||||
if listenRaw, ok := tlsConfig["listen"]; ok && listenRaw != nil {
|
||||
if data, err := json.Marshal(listenRaw); err == nil {
|
||||
var listenAddresses []map[string]interface{}
|
||||
if err := json.Unmarshal(data, &listenAddresses); err == nil {
|
||||
if len(listenAddresses) > 0 {
|
||||
if portRange, ok := listenAddresses[0]["portRange"].(string); ok && len(portRange) > 0 {
|
||||
port = portRange
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -83,7 +102,7 @@ func (this *TestAction) RunPost(params struct {
|
||||
query.Set("nonce", nonce)
|
||||
query.Set("sign", sign)
|
||||
}
|
||||
requestURL := "https://" + clusterDomain + "/resolve?" + query.Encode()
|
||||
requestURL := "https://" + clusterDomain + ":" + port + "/resolve?" + query.Encode()
|
||||
|
||||
resultCode := 1
|
||||
if strings.EqualFold(resp.GetCode(), "SUCCESS") {
|
||||
|
||||
@@ -430,9 +430,7 @@ func (this *userMustAuth) modules(userId int64, isVerified bool, isIdentified bo
|
||||
"code": "httpdns",
|
||||
"name": "HTTPDNS",
|
||||
"icon": "shield alternate",
|
||||
"isOn": registerConfig != nil &&
|
||||
registerConfig.HTTPDNSIsOn &&
|
||||
lists.ContainsString(featureCodes, userconfigs.UserFeatureCodeHTTPDNS),
|
||||
"isOn": lists.ContainsString(featureCodes, userconfigs.UserFeatureCodeHTTPDNS),
|
||||
"subItems": []maps.Map{
|
||||
{
|
||||
"name": "应用管理",
|
||||
|
||||
@@ -86,30 +86,31 @@
|
||||
<td class="title">App ID</td>
|
||||
<td>
|
||||
<code>{{settings.appId}}</code>
|
||||
<a href="" class="httpdns-mini-icon" title="复制 App ID" @click.prevent="copySecret(settings.appId, 'App ID')"><i class="copy outline icon"></i></a>
|
||||
<a href="" class="httpdns-mini-icon" title="复制 App ID"
|
||||
@click.prevent="copySecret(settings.appId, 'App ID')"><i class="copy outline icon"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">主服务域名</td>
|
||||
<td class="title">服务地址</td>
|
||||
<td>
|
||||
<code v-if="settings.primaryServiceDomain && settings.primaryServiceDomain.length > 0">{{settings.primaryServiceDomain}}</code>
|
||||
<span class="grey" v-else>未配置</span>
|
||||
<a v-if="settings.primaryServiceDomain && settings.primaryServiceDomain.length > 0" href="" class="httpdns-mini-icon" title="复制主服务域名" @click.prevent="copySecret(settings.primaryServiceDomain, '主服务域名')"><i class="copy outline icon"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">备用服务域名</td>
|
||||
<td>
|
||||
<code v-if="settings.backupServiceDomain && settings.backupServiceDomain.length > 0">{{settings.backupServiceDomain}}</code>
|
||||
<span class="grey" v-else>未配置</span>
|
||||
<a v-if="settings.backupServiceDomain && settings.backupServiceDomain.length > 0" href="" class="httpdns-mini-icon" title="复制备用服务域名" @click.prevent="copySecret(settings.backupServiceDomain, '备用服务域名')"><i class="copy outline icon"></i></a>
|
||||
<div v-if="settings.serviceAddresses && settings.serviceAddresses.length > 0">
|
||||
<div v-for="sa in settings.serviceAddresses" style="margin-bottom: 0.4em;">
|
||||
<code>{{sa.address}}</code>
|
||||
<a href="" class="httpdns-mini-icon" title="复制服务地址"
|
||||
@click.prevent="copySecret(sa.address, '服务地址')"><i class="copy outline icon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<span class="grey" v-else>未配置集群</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">请求验签</td>
|
||||
<td>
|
||||
<span :class="settings.signEnabled ? 'httpdns-state-on' : 'httpdns-state-off'">{{settings.signEnabled ? "已开启" : "已关闭"}}</span>
|
||||
<a href="" class="ui mini button basic" style="margin-left: .8em;" @click.prevent="toggleSignEnabled">{{settings.signEnabled ? "关闭请求验签" : "开启请求验签"}}</a>
|
||||
<span
|
||||
:class="settings.signEnabled ? 'httpdns-state-on' : 'httpdns-state-off'">{{settings.signEnabled
|
||||
? "已开启" : "已关闭"}}</span>
|
||||
<a href="" class="ui mini button basic" style="margin-left: .8em;"
|
||||
@click.prevent="toggleSignEnabled">{{settings.signEnabled ? "关闭请求验签" : "开启请求验签"}}</a>
|
||||
<p class="comment httpdns-note">打开后,服务端会对请求进行签名校验。</p>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -118,9 +119,14 @@
|
||||
<td>
|
||||
<div class="httpdns-secret-line">
|
||||
<code>{{signSecretVisible ? settings.signSecretPlain : settings.signSecretMasked}}</code>
|
||||
<a href="" class="httpdns-mini-icon" @click.prevent="signSecretVisible = !signSecretVisible" :title="signSecretVisible ? '隐藏明文' : '查看明文'"><i class="icon" :class="signSecretVisible ? 'eye slash' : 'eye'"></i></a>
|
||||
<a href="" class="httpdns-mini-icon" title="复制加签 Secret" @click.prevent="copySecret(settings.signSecretPlain, '加签 Secret')"><i class="copy outline icon"></i></a>
|
||||
<a href="" class="httpdns-mini-icon" title="重置加签 Secret" @click.prevent="resetSignSecret"><i class="redo icon"></i></a>
|
||||
<a href="" class="httpdns-mini-icon" @click.prevent="signSecretVisible = !signSecretVisible"
|
||||
:title="signSecretVisible ? '隐藏明文' : '查看明文'"><i class="icon"
|
||||
:class="signSecretVisible ? 'eye slash' : 'eye'"></i></a>
|
||||
<a href="" class="httpdns-mini-icon" title="复制加签 Secret"
|
||||
@click.prevent="copySecret(settings.signSecretPlain, '加签 Secret')"><i
|
||||
class="copy outline icon"></i></a>
|
||||
<a href="" class="httpdns-mini-icon" title="重置加签 Secret" @click.prevent="resetSignSecret"><i
|
||||
class="redo icon"></i></a>
|
||||
</div>
|
||||
<p class="comment httpdns-note">最近更新:{{settings.signSecretUpdatedAt}}</p>
|
||||
<p class="comment httpdns-note" v-if="!settings.signEnabled">请求验签已关闭,当前不使用加签 Secret。</p>
|
||||
@@ -131,4 +137,4 @@
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -18,15 +18,18 @@
|
||||
"西南": ["默认", "重庆", "四川", "贵州", "云南", "西藏"]
|
||||
};
|
||||
|
||||
vm.continents = ["默认", "非洲", "南极洲", "亚洲", "欧洲", "北美洲", "南美洲", "大洋洲"];
|
||||
vm.continents = ["默认", "亚洲", "欧洲", "北美洲", "南美洲", "非洲", "大洋洲"];
|
||||
vm.continentCountries = {
|
||||
"默认": ["默认"],
|
||||
"非洲": ["默认", "南非", "埃及", "尼日利亚", "肯尼亚", "摩洛哥"],
|
||||
"南极洲": ["默认"],
|
||||
"亚洲": ["默认", "中国香港", "中国澳门", "中国台湾", "日本", "韩国", "新加坡", "印度", "泰国", "越南"],
|
||||
"欧洲": ["默认", "德国", "英国", "法国", "荷兰", "西班牙", "意大利", "俄罗斯"],
|
||||
"北美洲": ["默认", "美国", "加拿大", "墨西哥"],
|
||||
"南美洲": ["默认", "巴西", "阿根廷", "智利", "哥伦比亚"],
|
||||
"亚洲": ["默认", "中国香港", "中国澳门", "中国台湾", "日本", "韩国", "新加坡", "印度", "泰国", "越南",
|
||||
"印度尼西亚", "马来西亚", "菲律宾", "柬埔寨", "缅甸", "老挝", "斯里兰卡", "孟加拉国", "巴基斯坦", "尼泊尔",
|
||||
"阿联酋", "沙特阿拉伯", "土耳其", "以色列", "伊朗", "伊拉克", "卡塔尔", "科威特", "蒙古"],
|
||||
"欧洲": ["默认", "德国", "英国", "法国", "荷兰", "西班牙", "意大利", "俄罗斯",
|
||||
"波兰", "瑞典", "瑞士", "挪威", "芬兰", "丹麦", "葡萄牙", "爱尔兰", "比利时", "奥地利",
|
||||
"乌克兰", "捷克", "罗马尼亚", "匈牙利", "希腊"],
|
||||
"北美洲": ["默认", "美国", "加拿大", "墨西哥", "巴拿马", "哥斯达黎加", "古巴"],
|
||||
"南美洲": ["默认", "巴西", "阿根廷", "智利", "哥伦比亚", "秘鲁", "委内瑞拉", "厄瓜多尔"],
|
||||
"非洲": ["默认", "南非", "埃及", "尼日利亚", "肯尼亚", "摩洛哥", "阿尔及利亚", "坦桑尼亚", "埃塞俄比亚", "加纳", "突尼斯"],
|
||||
"大洋洲": ["默认", "澳大利亚", "新西兰"]
|
||||
};
|
||||
|
||||
|
||||
@@ -58,5 +58,5 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<not-found-box v-if="!domains || domains.length == 0">当前应用尚未绑定域名。</not-found-box>
|
||||
<not-found-box v-if="domains && domains.length > 0 && filteredDomains().length == 0">没有匹配的域名。</not-found-box>
|
||||
<not-found-box v-if="domains.length == 0">当前应用尚未绑定域名。</not-found-box>
|
||||
<not-found-box v-if="domains.length > 0 && filteredDomains().length == 0">没有匹配的域名。</not-found-box>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
Tea.context(function () {
|
||||
var that = this;
|
||||
|
||||
if (typeof this.keywordInput == "undefined" || this.keywordInput == null) {
|
||||
this.keywordInput = "";
|
||||
}
|
||||
@@ -13,30 +15,29 @@
|
||||
this.keywordInput = String(this.keyword);
|
||||
|
||||
this.doSearch = function () {
|
||||
this.keyword = String(this.keywordInput || "").trim();
|
||||
that.keyword = String(that.keywordInput || "").trim();
|
||||
};
|
||||
|
||||
this.clearSearch = function () {
|
||||
this.keywordInput = "";
|
||||
this.keyword = "";
|
||||
that.keywordInput = "";
|
||||
that.keyword = "";
|
||||
};
|
||||
|
||||
this.filteredDomains = function () {
|
||||
let domains = Array.isArray(this.domains) ? this.domains : [];
|
||||
let keyword = String(this.keyword || "").trim().toLowerCase();
|
||||
let keyword = (that.keyword || "").trim().toLowerCase();
|
||||
if (keyword.length == 0) {
|
||||
return domains;
|
||||
return that.domains || [];
|
||||
}
|
||||
return domains.filter(function (domain) {
|
||||
return (that.domains || []).filter(function (domain) {
|
||||
let name = (domain.name || "").toLowerCase();
|
||||
return name.indexOf(keyword) >= 0;
|
||||
});
|
||||
};
|
||||
|
||||
this.bindDomain = function () {
|
||||
teaweb.popup("/httpdns/apps/domains/createPopup?appId=" + this.app.id, {
|
||||
height: "24em",
|
||||
width: "46em",
|
||||
teaweb.popup("/httpdns/apps/domains/createPopup?appId=" + that.app.id, {
|
||||
height: "12em",
|
||||
width: "36em",
|
||||
title: "添加域名",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
{$layout}
|
||||
{$template "menu"}
|
||||
|
||||
<div class="ui margin"></div>
|
||||
|
||||
<h3 class="ui header">HTTPDNS 鍏ㄥ眬绛栫暐</h3>
|
||||
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">鍏ㄥ眬榛樿瑙f瀽 TTL</td>
|
||||
<td><input type="text" name="defaultTTL" maxlength="8" v-model="policies.defaultTTL" /> 绉?/td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">鍏ㄥ眬榛樿 SNI 绛夌骇</td>
|
||||
<td>
|
||||
<select name="defaultSniPolicy" class="ui dropdown auto-width" v-model="policies.defaultSniPolicy">
|
||||
<option value="level1">level1锛堝浐瀹?SNI锛?/option>
|
||||
<option value="level2">level2锛堥殣鍖?SNI锛?/option>
|
||||
<option value="level3">level3锛圗CH锛?/option>
|
||||
</select>
|
||||
<div class="grey small" v-if="policies.defaultSniPolicy == 'level1'" style="margin-top:.5em;">
|
||||
level1 浠呬娇鐢ㄥ浐瀹?SNI锛屼笉鍚敤 ECS 鍜岃瘉涔︽牎楠岀瓥鐣ャ€? </div>
|
||||
<div class="grey small" v-else-if="policies.defaultSniPolicy == 'level2'" style="margin-top:.5em;">
|
||||
level2 浠呭惎鐢ㄩ殣鍖?SNI锛屼笉瑕佹眰閰嶇疆 ECS 涓庤瘉涔︾瓥鐣ャ€? </div>
|
||||
<div class="grey small" v-else style="margin-top:.5em;">
|
||||
level3 鍚敤 ECH锛屽缓璁悓鏃堕厤缃?ECS 涓庤瘉涔︽牎楠岀瓥鐣ャ€? </div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">鍏ㄥ眬闄嶇骇瓒呮椂</td>
|
||||
<td><input type="text" name="defaultFallbackMs" maxlength="8" v-model="policies.defaultFallbackMs" /> 姣</td>
|
||||
</tr>
|
||||
|
||||
<tr v-show="policies.defaultSniPolicy == 'level3'">
|
||||
<td class="title">全局 ECS 掩码策略</td>
|
||||
<td>
|
||||
<select name="ecsMode" class="ui dropdown auto-width" v-model="policies.ecsMode">
|
||||
<option value="off">鍏抽棴</option>
|
||||
<option value="auto">鑷姩</option>
|
||||
<option value="custom">鑷畾涔?/option>
|
||||
</select>
|
||||
<span v-if="policies.ecsMode == 'custom'">
|
||||
<span class="grey" style="margin-left:.8em;">IPv4 /</span>
|
||||
<input type="text" name="ecsIPv4Prefix" maxlength="3" v-model="policies.ecsIPv4Prefix" style="width:4.5em;" />
|
||||
<span class="grey" style="margin-left:.8em;">IPv6 /</span>
|
||||
<input type="text" name="ecsIPv6Prefix" maxlength="3" v-model="policies.ecsIPv6Prefix" style="width:4.5em;" />
|
||||
</span>
|
||||
<span v-else class="grey" style="margin-left:.8em;">仅在“自定义”模式下配置掩码。</span>
|
||||
|
||||
<input type="hidden" name="ecsIPv4Prefix" v-model="policies.ecsIPv4Prefix" v-if="policies.ecsMode != 'custom'" />
|
||||
<input type="hidden" name="ecsIPv6Prefix" v-model="policies.ecsIPv6Prefix" v-if="policies.ecsMode != 'custom'" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-show="policies.defaultSniPolicy == 'level3'">
|
||||
<td class="title">鍏ㄥ眬璇佷功鏍¢獙绛栫暐</td>
|
||||
<td>
|
||||
<span class="grey">证书指纹校验(Pinning)</span>
|
||||
<select name="pinningMode" class="ui dropdown auto-width" v-model="policies.pinningMode" style="margin-left:.4em;">
|
||||
<option value="off">鍏抽棴</option>
|
||||
<option value="report">瑙傚療妯″紡</option>
|
||||
<option value="enforce">寮哄埗鏍¢獙</option>
|
||||
</select>
|
||||
<span class="grey" style="margin-left:1.2em;">证书 SAN 域名校验</span>
|
||||
<select name="sanMode" class="ui dropdown auto-width" v-model="policies.sanMode" style="margin-left:.4em;">
|
||||
<option value="off">鍏抽棴</option>
|
||||
<option value="report">瑙傚療妯″紡</option>
|
||||
<option value="strict">涓ユ牸鏍¢獙</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功");
|
||||
|
||||
this.$delay(function () {
|
||||
this.$watch("policies.defaultSniPolicy", function (level) {
|
||||
if (level == "level1" || level == "level2") {
|
||||
this.policies.ecsMode = "off";
|
||||
this.policies.pinningMode = "off";
|
||||
this.policies.sanMode = "off";
|
||||
return;
|
||||
}
|
||||
|
||||
if (level == "level3") {
|
||||
if (this.policies.ecsMode == "off") {
|
||||
this.policies.ecsMode = "auto";
|
||||
}
|
||||
if (this.policies.pinningMode == "off") {
|
||||
this.policies.pinningMode = "report";
|
||||
}
|
||||
if (this.policies.sanMode == "off") {
|
||||
this.policies.sanMode = "strict";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.$watch("policies.ecsMode", function (mode) {
|
||||
if (this.policies.defaultSniPolicy != "level3") {
|
||||
return;
|
||||
}
|
||||
if (mode == "custom") {
|
||||
if (!this.policies.ecsIPv4Prefix || this.policies.ecsIPv4Prefix <= 0) {
|
||||
this.policies.ecsIPv4Prefix = 24;
|
||||
}
|
||||
if (!this.policies.ecsIPv6Prefix || this.policies.ecsIPv6Prefix <= 0) {
|
||||
this.policies.ecsIPv6Prefix = 56;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<select class="ui dropdown" name="clusterId" v-model="clusterId">
|
||||
<option value="">[HTTPDNS服务域名]</option>
|
||||
<option value="">[API服务地址]</option>
|
||||
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.displayName}}</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -60,7 +60,7 @@
|
||||
<table class="ui table selectable celled">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>HTTPDNS服务域名</th>
|
||||
<th>API服务地址</th>
|
||||
<th>域名</th>
|
||||
<th>类型</th>
|
||||
<th>概要</th>
|
||||
@@ -91,4 +91,4 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -17,10 +17,11 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>HTTPDNS服务域名 *</label>
|
||||
<label>API服务地址 *</label>
|
||||
<select class="ui dropdown" name="clusterId" v-model="request.clusterId">
|
||||
<option value="">[请选择HTTPDNS服务域名]</option>
|
||||
<option v-for="cluster in currentClusters" :value="String(cluster.id)">{{cluster.displayName || cluster.name}}</option>
|
||||
<option value="">[请选择API服务地址]</option>
|
||||
<option v-for="cluster in currentClusters" :value="String(cluster.id)">{{cluster.displayName
|
||||
|| cluster.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
@@ -98,7 +99,8 @@
|
||||
<div class="ui segment">
|
||||
<div class="grey">客户端 IP</div>
|
||||
<div style="margin-top:.4em;">
|
||||
<code>{{response.data.client_ip || request.clientIp || '-'}}</code></div>
|
||||
<code>{{response.data.client_ip || request.clientIp || '-'}}</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
@@ -144,4 +146,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,8 +58,7 @@
|
||||
this.request.domain = ""
|
||||
}
|
||||
|
||||
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 appClusterIds = Array.isArray(selectedApp.clusterIds) ? selectedApp.clusterIds.map(Number) : []
|
||||
|
||||
let allowed = []
|
||||
for (let i = 0; i < this.clusters.length; i++) {
|
||||
@@ -68,7 +67,7 @@
|
||||
if (clusterId <= 0) {
|
||||
continue
|
||||
}
|
||||
if (clusterId === primaryClusterId || clusterId === backupClusterId) {
|
||||
if (appClusterIds.indexOf(clusterId) >= 0) {
|
||||
allowed.push(cluster)
|
||||
}
|
||||
}
|
||||
@@ -120,7 +119,7 @@
|
||||
return
|
||||
}
|
||||
if (this.request.clusterId.length === 0) {
|
||||
teaweb.warn("当前应用未绑定可用的 HTTPDNS 服务域名,请先在应用设置中配置主/备集群")
|
||||
teaweb.warn("当前应用未绑定可用集群,请先在应用设置中配置所属集群")
|
||||
return
|
||||
}
|
||||
if (this.request.domain.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user