diff --git a/internal/web/actions/default/clusters/cluster/settings/dns/index.go b/internal/web/actions/default/clusters/cluster/settings/dns/index.go new file mode 100644 index 00000000..e82c1fe4 --- /dev/null +++ b/internal/web/actions/default/clusters/cluster/settings/dns/index.go @@ -0,0 +1,92 @@ +package dns + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/oplogs" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dns/domains/domainutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/actions" +) + +type IndexAction struct { + actionutils.ParentAction +} + +func (this *IndexAction) Init() { + this.Nav("", "setting", "") + this.SecondMenu("dns") +} + +func (this *IndexAction) RunGet(params struct { + ClusterId int64 +}) { + // 是否有域名可选 + hasDomainsResp, err := this.RPC().DNSDomainRPC().ExistAvailableDomains(this.AdminContext(), &pb.ExistAvailableDomainsRequest{}) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["hasDomains"] = hasDomainsResp.Exist + + // 当前集群的DNS信息 + this.Data["domainId"] = 0 + this.Data["domainName"] = "" + this.Data["dnsName"] = "" + + dnsInfoResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: params.ClusterId}) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["dnsName"] = dnsInfoResp.Name + if dnsInfoResp.Domain != nil { + this.Data["domainId"] = dnsInfoResp.Domain.Id + this.Data["domainName"] = dnsInfoResp.Domain.Name + } + + this.Show() +} + +func (this *IndexAction) RunPost(params struct { + ClusterId int64 + + DnsDomainId int64 + DnsName string + + Must *actions.Must + CSRF *actionutils.CSRF +}) { + // 创建日志 + this.CreateLog(oplogs.LevelInfo, "修改集群 %d DNS设置", params.ClusterId) + + // 检查DNS名称 + if len(params.DnsName) > 0 { + if !domainutils.ValidateDomainFormat(params.DnsName) { + this.FailField("dnsName", "请输入正确的DNS子域名") + } + + // 检查是否已经被使用 + resp, err := this.RPC().NodeClusterRPC().CheckNodeClusterDNSName(this.AdminContext(), &pb.CheckNodeClusterDNSNameRequest{ + NodeClusterId: params.ClusterId, + DnsName: params.DnsName, + }) + if err != nil { + this.ErrorPage(err) + return + } + if resp.IsUsed { + this.FailField("dnsName", "此DNS子域名已经被使用,请换一个再试") + } + } + + _, err := this.RPC().NodeClusterRPC().UpdateNodeClusterDNS(this.AdminContext(), &pb.UpdateNodeClusterDNSRequest{ + NodeClusterId: params.ClusterId, + DnsName: params.DnsName, + DnsDomainId: params.DnsDomainId, + }) + if err != nil { + this.ErrorPage(err) + return + } + this.Success() +} diff --git a/internal/web/actions/default/clusters/cluster/settings/init.go b/internal/web/actions/default/clusters/cluster/settings/init.go index b52e16df..b346293d 100644 --- a/internal/web/actions/default/clusters/cluster/settings/init.go +++ b/internal/web/actions/default/clusters/cluster/settings/init.go @@ -1,6 +1,7 @@ package settings import ( + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/dns" clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/helpers" "github.com/iwind/TeaGo" @@ -15,6 +16,10 @@ func init() { GetPost("", new(IndexAction)). GetPost("/health", new(HealthAction)). GetPost("/healthRunPopup", new(HealthRunPopupAction)). + + // DNS + GetPost("/dns", new(dns.IndexAction)). + EndAll() }) } diff --git a/internal/web/actions/default/clusters/clusterutils/cluster_helper.go b/internal/web/actions/default/clusters/clusterutils/cluster_helper.go index e0af9612..58df7f44 100644 --- a/internal/web/actions/default/clusters/clusterutils/cluster_helper.go +++ b/internal/web/actions/default/clusters/clusterutils/cluster_helper.go @@ -11,6 +11,7 @@ import ( "strconv" ) +// 单个集群的帮助 type ClusterHelper struct { } @@ -81,5 +82,10 @@ func (this *ClusterHelper) createSettingMenu(clusterId string, selectedItem stri "url": "/clusters/cluster/settings/health?clusterId=" + clusterId, "isActive": selectedItem == "health", }) + items = append(items, maps.Map{ + "name": "DNS设置", + "url": "/clusters/cluster/settings/dns?clusterId=" + clusterId, + "isActive": selectedItem == "dns", + }) return } diff --git a/internal/web/actions/default/clusters/create.go b/internal/web/actions/default/clusters/create.go index 1e53d9bf..a20782bd 100644 --- a/internal/web/actions/default/clusters/create.go +++ b/internal/web/actions/default/clusters/create.go @@ -3,6 +3,7 @@ package clusters import ( "github.com/TeaOSLab/EdgeAdmin/internal/oplogs" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dns/domains/domainutils" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/actions" ) @@ -16,24 +17,61 @@ func (this *CreateAction) Init() { } func (this *CreateAction) RunGet(params struct{}) { + hasDomainsResp, err := this.RPC().DNSDomainRPC().ExistAvailableDomains(this.AdminContext(), &pb.ExistAvailableDomainsRequest{}) + if err != nil { + this.ErrorPage(err) + return + } + this.Data["hasDomains"] = hasDomainsResp.Exist + this.Show() } func (this *CreateAction) RunPost(params struct { - Name string + Name string + + // SSH相关 GrantId int64 InstallDir string + // DNS相关 + DnsDomainId int64 + DnsName string + Must *actions.Must }) { params.Must. Field("name", params.Name). Require("请输入集群名称") + // 检查DNS名称 + if len(params.DnsName) > 0 { + if !domainutils.ValidateDomainFormat(params.DnsName) { + this.FailField("dnsName", "请输入正确的DNS子域名") + } + + // 检查是否已经被使用 + resp, err := this.RPC().NodeClusterRPC().CheckNodeClusterDNSName(this.AdminContext(), &pb.CheckNodeClusterDNSNameRequest{ + NodeClusterId: 0, + DnsName: params.DnsName, + }) + if err != nil { + this.ErrorPage(err) + return + } + if resp.IsUsed { + this.FailField("dnsName", "此DNS子域名已经被使用,请换一个再试") + } + } + + // TODO 检查DnsDomainId的有效性 + createResp, err := this.RPC().NodeClusterRPC().CreateNodeCluster(this.AdminContext(), &pb.CreateNodeClusterRequest{ - Name: params.Name, - GrantId: params.GrantId, - InstallDir: params.InstallDir, + Name: params.Name, + GrantId: params.GrantId, + InstallDir: params.InstallDir, + DnsDomainId: params.DnsDomainId, + DnsName: params.DnsName, }) if err != nil { this.ErrorPage(err) @@ -41,7 +79,7 @@ func (this *CreateAction) RunPost(params struct { } // 创建日志 - this.CreateLog(oplogs.LevelInfo, "创建集群:%d", createResp.ClusterId) + this.CreateLog(oplogs.LevelInfo, "创建节点集群:%d", createResp.ClusterId) this.Success() } diff --git a/internal/web/actions/default/dns/domains/selectPopup.go b/internal/web/actions/default/dns/domains/selectPopup.go new file mode 100644 index 00000000..d16b24cb --- /dev/null +++ b/internal/web/actions/default/dns/domains/selectPopup.go @@ -0,0 +1,91 @@ +package domains + +import ( + "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 SelectPopupAction struct { + actionutils.ParentAction +} + +func (this *SelectPopupAction) Init() { + this.Nav("", "", "") +} + +func (this *SelectPopupAction) RunGet(params struct { + DomainId int64 +}) { + this.Data["domainId"] = 0 + this.Data["domainName"] = "" + this.Data["providerId"] = 0 + this.Data["providerType"] = "" + + // 域名信息 + if params.DomainId > 0 { + domainResp, err := this.RPC().DNSDomainRPC().FindEnabledDNSDomain(this.AdminContext(), &pb.FindEnabledDNSDomainRequest{DnsDomainId: params.DomainId}) + if err != nil { + this.ErrorPage(err) + return + } + domain := domainResp.DnsDomain + if domain != nil { + this.Data["domainId"] = domain.Id + this.Data["domainName"] = domain.Name + this.Data["providerId"] = domain.ProviderId + + providerResp, err := this.RPC().DNSProviderRPC().FindEnabledDNSProvider(this.AdminContext(), &pb.FindEnabledDNSProviderRequest{DnsProviderId: domain.ProviderId}) + if err != nil { + this.ErrorPage(err) + return + } + if providerResp.DnsProvider != nil { + this.Data["providerType"] = providerResp.DnsProvider.Type + } + } + } + + // 所有服务商 + providerTypesResp, err := this.RPC().DNSProviderRPC().FindAllDNSProviderTypes(this.AdminContext(), &pb.FindAllDNSProviderTypesRequest{}) + if err != nil { + this.ErrorPage(err) + return + } + providerTypeMaps := []maps.Map{} + for _, providerType := range providerTypesResp.ProviderTypes { + providerTypeMaps = append(providerTypeMaps, maps.Map{ + "name": providerType.Name, + "code": providerType.Code, + }) + } + this.Data["providerTypes"] = providerTypeMaps + + this.Show() +} + +func (this *SelectPopupAction) RunPost(params struct { + DomainId int64 + + Must *actions.Must + CSRF *actionutils.CSRF +}) { + this.Data["domainId"] = params.DomainId + this.Data["domainName"] = "" + + if params.DomainId > 0 { + domainResp, err := this.RPC().DNSDomainRPC().FindEnabledDNSDomain(this.AdminContext(), &pb.FindEnabledDNSDomainRequest{DnsDomainId: params.DomainId}) + if err != nil { + this.ErrorPage(err) + return + } + if domainResp.DnsDomain != nil { + this.Data["domainName"] = domainResp.DnsDomain.Name + } else { + this.Data["domainId"] = 0 + } + } + + this.Success() +} diff --git a/internal/web/actions/default/dns/init.go b/internal/web/actions/default/dns/init.go index 23f6410f..5a6a798e 100644 --- a/internal/web/actions/default/dns/init.go +++ b/internal/web/actions/default/dns/init.go @@ -43,6 +43,7 @@ func init() { Post("/delete", new(domains.DeleteAction)). Post("/sync", new(domains.SyncAction)). Get("/routesPopup", new(domains.RoutesPopupAction)). + GetPost("/selectPopup", new(domains.SelectPopupAction)). EndData(). // 问题修复 diff --git a/internal/web/actions/default/servers/index.go b/internal/web/actions/default/servers/index.go index f0b2fda9..bed36f40 100644 --- a/internal/web/actions/default/servers/index.go +++ b/internal/web/actions/default/servers/index.go @@ -127,6 +127,14 @@ func (this *IndexAction) RunGet(params struct { return } } + countServerNames := 0 + for _, serverName := range serverNames { + if len(serverName.SubNames) == 0 { + countServerNames++ + } else { + countServerNames += len(serverName.SubNames) + } + } serverMaps = append(serverMaps, maps.Map{ "id": server.Id, @@ -136,10 +144,11 @@ func (this *IndexAction) RunGet(params struct { "id": server.Cluster.Id, "name": server.Cluster.Name, }, - "ports": portMaps, - "serverTypeName": serverconfigs.FindServerType(server.Type).GetString("name"), - "groups": groupMaps, - "serverNames": serverNames, + "ports": portMaps, + "serverTypeName": serverconfigs.FindServerType(server.Type).GetString("name"), + "groups": groupMaps, + "serverNames": serverNames, + "countServerNames": countServerNames, }) } this.Data["servers"] = serverMaps diff --git a/internal/web/helpers/user_must_auth.go b/internal/web/helpers/user_must_auth.go index 1804714a..d2db6bb1 100644 --- a/internal/web/helpers/user_must_auth.go +++ b/internal/web/helpers/user_must_auth.go @@ -82,7 +82,7 @@ func (this *UserMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam modules := []maps.Map{ { "code": "servers", - "name": "代理服务", + "name": "网站服务", "icon": "clone outsize", "subItems": []maps.Map{ { @@ -94,7 +94,7 @@ func (this *UserMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam }, { "code": "clusters", - "name": "节点集群", + "name": "边缘节点", "icon": "cloud", "subItems": []maps.Map{ { diff --git a/web/public/js/components/dns/dns-domain-selector.js b/web/public/js/components/dns/dns-domain-selector.js new file mode 100644 index 00000000..de823a97 --- /dev/null +++ b/web/public/js/components/dns/dns-domain-selector.js @@ -0,0 +1,54 @@ +Vue.component("dns-domain-selector", { + props: ["v-domain-id", "v-domain-name"], + data: function () { + let domainId = this.vDomainId + if (domainId == null) { + domainId = 0 + } + let domainName = this.vDomainName + if (domainName == null) { + domainName = "" + } + return { + domainId: domainId, + domainName: domainName + } + }, + methods: { + select: function () { + let that = this + teaweb.popup("/dns/domains/selectPopup", { + callback: function (resp) { + that.domainId = resp.data.domainId + that.domainName = resp.data.domainName + } + }) + }, + remove: function() { + this.domainId = 0 + this.domainName = "" + }, + update: function () { + let that = this + teaweb.popup("/dns/domains/selectPopup?domainId=" + this.domainId, { + callback: function (resp) { + that.domainId = resp.data.domainId + that.domainName = resp.data.domainName + } + }) + } + }, + template: `
当节点没有单独设置安装目录时,默认使用此设置。如果集群和节点都没有设置安装目录,则使用/$登录用户/edge-node 目录。
diff --git a/web/views/@default/clusters/create.html b/web/views/@default/clusters/create.html index fa75d1b1..237d8cbd 100644 --- a/web/views/@default/clusters/create.html +++ b/web/views/@default/clusters/create.html @@ -9,20 +9,47 @@| 默认SSH登录方式 | +默认SSH登录方式 |
当节点没有单独设置SSH登录方式时,默认使用此设置。 |
| 默认安装目录 | +节点安装目录 |
- 当节点没有单独设置安装目录时,默认使用此设置。如果集群和节点都没有设置安装目录,则使用/$登录用户/edge-node 目录。 +当节点没有单独设置安装目录时,默认使用此设置。如果集群和节点都没有设置安装目录,则使用/$登录用户/edge-node + 目录。 |
| 选择主域名 | +
+ 用于生成集群节点和网站服务的DNS解析记录。 + |
+
| DNS子域名 | +
+
+
+ .主域名
+
+ 和主域名一起组成子域名。 + |
+