Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0b908bcaa | ||
|
|
3de25d4fe1 | ||
|
|
07194855bf | ||
|
|
d0f1eb13ee | ||
|
|
a0930bfd74 | ||
|
|
08cff8affc | ||
|
|
02132e9262 | ||
|
|
61b6a49885 | ||
|
|
896e54ebe8 | ||
|
|
1b36bad60a | ||
|
|
fc14800d70 | ||
|
|
fa61f277e4 | ||
|
|
9117309472 | ||
|
|
6bb2977d59 | ||
|
|
df9dce76cb | ||
|
|
4cb9c85a1c | ||
|
|
f4f5389ffb | ||
|
|
5d336eb77d | ||
|
|
c552eb3b0e | ||
|
|
455952e9e4 | ||
|
|
7132401c7f | ||
|
|
a4dddfb139 | ||
|
|
7ef32bad97 | ||
|
|
732513a644 | ||
|
|
756cf4a9ae | ||
|
|
a15a630265 | ||
|
|
3fab1b8294 | ||
|
|
215635f429 | ||
|
|
dbb1ae180b | ||
|
|
e8d4d01d85 | ||
|
|
6593989a84 |
@@ -95,9 +95,6 @@ function build() {
|
|||||||
cp -R "$ROOT"/deploy "$DIST/"
|
cp -R "$ROOT"/deploy "$DIST/"
|
||||||
rm -f "$DIST"/deploy/.gitignore
|
rm -f "$DIST"/deploy/.gitignore
|
||||||
cp -R "$ROOT"/installers "$DIST"/
|
cp -R "$ROOT"/installers "$DIST"/
|
||||||
cp -R "$ROOT"/resources "$DIST"/
|
|
||||||
rm -f "$DIST"/resources/ipdata/ip2region/global_region.csv
|
|
||||||
rm -f "$DIST"/resources/ipdata/ip2region/ip.merge.txt
|
|
||||||
|
|
||||||
# building edge installer
|
# building edge installer
|
||||||
echo "building node installer ..."
|
echo "building node installer ..."
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -14,7 +14,6 @@ import (
|
|||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"github.com/iwind/gosock/pkg/gosock"
|
"github.com/iwind/gosock/pkg/gosock"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
@@ -130,7 +129,7 @@ func main() {
|
|||||||
flagSet.BoolVar(&formatJSON, "json", false, "")
|
flagSet.BoolVar(&formatJSON, "json", false, "")
|
||||||
_ = flagSet.Parse(os.Args[2:])
|
_ = flagSet.Parse(os.Args[2:])
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(Tea.LogFile("issues.log"))
|
data, err := os.ReadFile(Tea.LogFile("issues.log"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if formatJSON {
|
if formatJSON {
|
||||||
fmt.Print("[]")
|
fmt.Print("[]")
|
||||||
|
|||||||
@@ -1,193 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
|
|
||||||
"github.com/iwind/TeaGo/Tea"
|
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"github.com/iwind/TeaGo/lists"
|
|
||||||
"github.com/iwind/TeaGo/logs"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// 导入数据
|
|
||||||
if lists.ContainsString(os.Args, "import") {
|
|
||||||
dbs.NotifyReady()
|
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(Tea.Root + "/resources/ipdata/ip2region/global_region.csv")
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(data) == 0 {
|
|
||||||
logs.Println("[ERROR]file content should not be empty")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lines := bytes.Split(data, []byte{'\n'})
|
|
||||||
for _, line := range lines {
|
|
||||||
line = bytes.TrimSpace(line)
|
|
||||||
if len(line) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
s := string(line)
|
|
||||||
reg := regexp.MustCompile(`(?U)(\d+),(\d+),(.+),(\d+),`)
|
|
||||||
if !reg.MatchString(s) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
result := reg.FindStringSubmatch(s)
|
|
||||||
dataId := result[1]
|
|
||||||
parentDataId := result[2]
|
|
||||||
name := result[3]
|
|
||||||
level := result[4]
|
|
||||||
|
|
||||||
switch level {
|
|
||||||
case "1": // 国家|地区
|
|
||||||
countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithDataId(nil, dataId)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if countryId == 0 {
|
|
||||||
logs.Println("creating country or region ", name)
|
|
||||||
_, err = regions.SharedRegionCountryDAO.CreateCountry(nil, name, dataId)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "2": // 省份|地区
|
|
||||||
provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithDataId(nil, dataId)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if provinceId == 0 {
|
|
||||||
logs.Println("creating province", name)
|
|
||||||
|
|
||||||
countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithDataId(nil, parentDataId)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if countryId == 0 {
|
|
||||||
logs.Println("[ERROR]can not find country from data id '" + parentDataId + "'")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = regions.SharedRegionProvinceDAO.CreateProvince(nil, countryId, name, dataId)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "3": // 城市
|
|
||||||
cityId, err := regions.SharedRegionCityDAO.FindCityWithDataId(nil, dataId)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cityId == 0 {
|
|
||||||
logs.Println("creating city", name)
|
|
||||||
|
|
||||||
provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithDataId(nil, parentDataId)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = regions.SharedRegionCityDAO.CreateCity(nil, provinceId, name, dataId)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logs.Println("done")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查数据
|
|
||||||
if lists.ContainsString(os.Args, "check") {
|
|
||||||
dbs.NotifyReady()
|
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(Tea.Root + "/resources/ipdata/ip2region/ip.merge.txt")
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(data) == 0 {
|
|
||||||
logs.Println("[ERROR]file should not be empty")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lines := bytes.Split(data, []byte("\n"))
|
|
||||||
for index, line := range lines {
|
|
||||||
s := string(bytes.TrimSpace(line))
|
|
||||||
if len(s) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pieces := strings.Split(s, "|")
|
|
||||||
countryName := pieces[2]
|
|
||||||
provinceName := pieces[4]
|
|
||||||
providerName := pieces[6]
|
|
||||||
|
|
||||||
// 记录provider
|
|
||||||
if len(providerName) > 0 && providerName != "0" {
|
|
||||||
providerId, err := regions.SharedRegionProviderDAO.FindProviderIdWithNameCacheable(nil, providerName)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]find provider id failed: " + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if providerId == 0 {
|
|
||||||
logs.Println("creating new provider '"+providerName+"' ... ", index, "line")
|
|
||||||
_, err = regions.SharedRegionProviderDAO.CreateProvider(nil, providerName)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("create new provider failed: " + providerName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logs.Println("created new provider '" + providerName + "'")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if lists.ContainsString([]string{"0", "欧洲", "北美地区", "法国南部领地", "非洲地区", "亚太地区"}, countryName) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查国家
|
|
||||||
countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithNameCacheable(nil, countryName)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if countryId == 0 {
|
|
||||||
logs.Println("[ERROR]can not find country '"+countryName+"', index: ", index, "data: "+s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查省份
|
|
||||||
if countryName == "中国" {
|
|
||||||
if lists.ContainsString([]string{"0"}, provinceName) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithNameCacheable(nil, countryId, provinceName)
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[ERROR]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if provinceId == 0 {
|
|
||||||
logs.Println("[ERROR]can not find province '"+provinceName+"', index: ", index, "data: "+s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logs.Println("done")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"go/format"
|
"go/format"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -67,7 +66,7 @@ func init() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(sqlFile, dst, 0666)
|
err = os.WriteFile(sqlFile, dst, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[ERROR]write file failed: " + err.Error())
|
fmt.Println("[ERROR]write file failed: " + err.Error())
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ func (this *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||||||
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
// 设置记录
|
// 设置记录
|
||||||
index := strings.Index(fqdn, "."+this.dnsDomain)
|
var index = strings.Index(fqdn, "."+this.dnsDomain)
|
||||||
if index < 0 {
|
if index < 0 {
|
||||||
return errors.New("invalid fqdn value")
|
return errors.New("invalid fqdn value")
|
||||||
}
|
}
|
||||||
recordName := fqdn[:index]
|
var recordName = fqdn[:index]
|
||||||
record, err := this.raw.QueryRecord(this.dnsDomain, recordName, dnstypes.RecordTypeTXT)
|
record, err := this.raw.QueryRecord(this.dnsDomain, recordName, dnstypes.RecordTypeTXT)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("query DNS record failed: " + err.Error())
|
return errors.New("query DNS record failed: " + err.Error())
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func (this *Request) runDNS() (certData []byte, keyData []byte, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
config := lego.NewConfig(this.task.User)
|
var config = lego.NewConfig(this.task.User)
|
||||||
config.Certificate.KeyType = certcrypto.RSA2048
|
config.Certificate.KeyType = certcrypto.RSA2048
|
||||||
config.CADirURL = this.task.Provider.APIURL
|
config.CADirURL = this.task.Provider.APIURL
|
||||||
config.UserAgent = teaconst.ProductName + "/" + teaconst.Version
|
config.UserAgent = teaconst.ProductName + "/" + teaconst.Version
|
||||||
@@ -86,7 +86,7 @@ func (this *Request) runDNS() (certData []byte, keyData []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 注册用户
|
// 注册用户
|
||||||
resource := this.task.User.GetRegistration()
|
var resource = this.task.User.GetRegistration()
|
||||||
if resource != nil {
|
if resource != nil {
|
||||||
resource, err = client.Registration.QueryRegistration()
|
resource, err = client.Registration.QueryRegistration()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -124,7 +124,7 @@ func (this *Request) runDNS() (certData []byte, keyData []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 申请证书
|
// 申请证书
|
||||||
request := certificate.ObtainRequest{
|
var request = certificate.ObtainRequest{
|
||||||
Domains: this.task.Domains,
|
Domains: this.task.Domains,
|
||||||
Bundle: true,
|
Bundle: true,
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ func (this *Request) runHTTP() (certData []byte, keyData []byte, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
config := lego.NewConfig(this.task.User)
|
var config = lego.NewConfig(this.task.User)
|
||||||
config.Certificate.KeyType = certcrypto.RSA2048
|
config.Certificate.KeyType = certcrypto.RSA2048
|
||||||
config.CADirURL = this.task.Provider.APIURL
|
config.CADirURL = this.task.Provider.APIURL
|
||||||
config.UserAgent = teaconst.ProductName + "/" + teaconst.Version
|
config.UserAgent = teaconst.ProductName + "/" + teaconst.Version
|
||||||
@@ -157,7 +157,7 @@ func (this *Request) runHTTP() (certData []byte, keyData []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 注册用户
|
// 注册用户
|
||||||
resource := this.task.User.GetRegistration()
|
var resource = this.task.User.GetRegistration()
|
||||||
if resource != nil {
|
if resource != nil {
|
||||||
resource, err = client.Registration.QueryRegistration()
|
resource, err = client.Registration.QueryRegistration()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -195,7 +195,7 @@ func (this *Request) runHTTP() (certData []byte, keyData []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 申请证书
|
// 申请证书
|
||||||
request := certificate.ObtainRequest{
|
var request = certificate.ObtainRequest{
|
||||||
Domains: this.task.Domains,
|
Domains: this.task.Domains,
|
||||||
Bundle: true,
|
Bundle: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "0.5.0"
|
Version = "0.5.2"
|
||||||
|
|
||||||
ProductName = "Edge API"
|
ProductName = "Edge API"
|
||||||
ProcessName = "edge-api"
|
ProcessName = "edge-api"
|
||||||
@@ -18,11 +18,11 @@ const (
|
|||||||
|
|
||||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||||
|
|
||||||
NodeVersion = "0.5.0"
|
NodeVersion = "0.5.2"
|
||||||
UserNodeVersion = "0.4.0"
|
UserNodeVersion = "0.4.1"
|
||||||
AuthorityNodeVersion = "0.0.2"
|
AuthorityNodeVersion = "0.0.2"
|
||||||
MonitorNodeVersion = "0.0.4"
|
MonitorNodeVersion = "0.0.4"
|
||||||
DNSNodeVersion = "0.2.5"
|
DNSNodeVersion = "0.2.6"
|
||||||
ReportNodeVersion = "0.1.1"
|
ReportNodeVersion = "0.1.1"
|
||||||
|
|
||||||
// SQLVersion SQL版本号
|
// SQLVersion SQL版本号
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
@@ -72,8 +73,9 @@ func (this *ACMEProviderAccountDAO) FindACMEProviderAccountName(tx *dbs.Tx, id i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateAccount 创建账号
|
// CreateAccount 创建账号
|
||||||
func (this *ACMEProviderAccountDAO) CreateAccount(tx *dbs.Tx, name string, providerCode string, eabKid string, eabKey string) (int64, error) {
|
func (this *ACMEProviderAccountDAO) CreateAccount(tx *dbs.Tx, userId int64, name string, providerCode string, eabKid string, eabKey string) (int64, error) {
|
||||||
var op = NewACMEProviderAccountOperator()
|
var op = NewACMEProviderAccountOperator()
|
||||||
|
op.UserId = userId
|
||||||
op.Name = name
|
op.Name = name
|
||||||
op.ProviderCode = providerCode
|
op.ProviderCode = providerCode
|
||||||
op.EabKid = eabKid
|
op.EabKid = eabKid
|
||||||
@@ -98,15 +100,18 @@ func (this *ACMEProviderAccountDAO) UpdateAccount(tx *dbs.Tx, accountId int64, n
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CountAllEnabledAccounts 计算账号数量
|
// CountAllEnabledAccounts 计算账号数量
|
||||||
func (this *ACMEProviderAccountDAO) CountAllEnabledAccounts(tx *dbs.Tx) (int64, error) {
|
func (this *ACMEProviderAccountDAO) CountAllEnabledAccounts(tx *dbs.Tx, userId int64) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
|
State(ACMEProviderAccountStateEnabled).
|
||||||
|
Attr("userId", userId).
|
||||||
Count()
|
Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListEnabledAccounts 查找单页账号
|
// ListEnabledAccounts 查找单页账号
|
||||||
func (this *ACMEProviderAccountDAO) ListEnabledAccounts(tx *dbs.Tx, offset int64, size int64) (result []*ACMEProviderAccount, err error) {
|
func (this *ACMEProviderAccountDAO) ListEnabledAccounts(tx *dbs.Tx, userId int64, offset int64, size int64) (result []*ACMEProviderAccount, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(ACMEProviderAccountStateEnabled).
|
State(ACMEProviderAccountStateEnabled).
|
||||||
|
Attr("userId", userId).
|
||||||
Offset(offset).
|
Offset(offset).
|
||||||
Limit(size).
|
Limit(size).
|
||||||
DescPk().
|
DescPk().
|
||||||
@@ -116,12 +121,34 @@ func (this *ACMEProviderAccountDAO) ListEnabledAccounts(tx *dbs.Tx, offset int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledAccountsWithProviderCode 根据服务商代号查找账号
|
// FindAllEnabledAccountsWithProviderCode 根据服务商代号查找账号
|
||||||
func (this *ACMEProviderAccountDAO) FindAllEnabledAccountsWithProviderCode(tx *dbs.Tx, providerCode string) (result []*ACMEProviderAccount, err error) {
|
func (this *ACMEProviderAccountDAO) FindAllEnabledAccountsWithProviderCode(tx *dbs.Tx, userId int64, providerCode string) (result []*ACMEProviderAccount, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(ACMEProviderAccountStateEnabled).
|
State(ACMEProviderAccountStateEnabled).
|
||||||
Attr("providerCode", providerCode).
|
Attr("providerCode", providerCode).
|
||||||
|
Attr("userId", userId).
|
||||||
DescPk().
|
DescPk().
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckUserAccount 检查是否为用户的服务商账号
|
||||||
|
func (this *ACMEProviderAccountDAO) CheckUserAccount(tx *dbs.Tx, userId int64, accountId int64) error {
|
||||||
|
if userId <= 0 || accountId <= 0 {
|
||||||
|
return models.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := this.Query(tx).
|
||||||
|
Pk(accountId).
|
||||||
|
State(ACMEProviderAccountStateEnabled).
|
||||||
|
Attr("userId", userId).
|
||||||
|
Exist()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !b {
|
||||||
|
return models.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,24 +3,26 @@ package acme
|
|||||||
// ACMEProviderAccount ACME提供商
|
// ACMEProviderAccount ACME提供商
|
||||||
type ACMEProviderAccount struct {
|
type ACMEProviderAccount struct {
|
||||||
Id uint64 `field:"id"` // ID
|
Id uint64 `field:"id"` // ID
|
||||||
|
UserId uint64 `field:"userId"` // 用户ID
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
ProviderCode string `field:"providerCode"` // 代号
|
ProviderCode string `field:"providerCode"` // 代号
|
||||||
Error string `field:"error"` // 最后一条错误信息
|
|
||||||
EabKid string `field:"eabKid"` // KID
|
EabKid string `field:"eabKid"` // KID
|
||||||
EabKey string `field:"eabKey"` // Key
|
EabKey string `field:"eabKey"` // Key
|
||||||
|
Error string `field:"error"` // 最后一条错误信息
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
type ACMEProviderAccountOperator struct {
|
type ACMEProviderAccountOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
IsOn interface{} // 是否启用
|
UserId any // 用户ID
|
||||||
Name interface{} // 名称
|
IsOn any // 是否启用
|
||||||
ProviderCode interface{} // 代号
|
Name any // 名称
|
||||||
Error interface{} // 最后一条错误信息
|
ProviderCode any // 代号
|
||||||
EabKid interface{} // KID
|
EabKid any // KID
|
||||||
EabKey interface{} // Key
|
EabKey any // Key
|
||||||
State interface{} // 状态
|
Error any // 最后一条错误信息
|
||||||
|
State any // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewACMEProviderAccountOperator() *ACMEProviderAccountOperator {
|
func NewACMEProviderAccountOperator() *ACMEProviderAccountOperator {
|
||||||
|
|||||||
@@ -107,7 +107,11 @@ func (this *ACMETaskDAO) DisableAllTasksWithCertId(tx *dbs.Tx, certId int64) err
|
|||||||
|
|
||||||
// CountAllEnabledACMETasks 计算所有任务数量
|
// CountAllEnabledACMETasks 计算所有任务数量
|
||||||
func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string) (int64, error) {
|
func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string) (int64, error) {
|
||||||
query := dbutils.NewQuery(tx, this, adminId, userId)
|
var query = this.Query(tx)
|
||||||
|
if adminId > 0 {
|
||||||
|
query.Attr("adminId", adminId)
|
||||||
|
}
|
||||||
|
query.Attr("userId", userId) // 这个条件必须加上
|
||||||
if isAvailable || isExpired || expiringDays > 0 {
|
if isAvailable || isExpired || expiringDays > 0 {
|
||||||
query.Gt("certId", 0)
|
query.Gt("certId", 0)
|
||||||
|
|
||||||
@@ -138,7 +142,11 @@ func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, adminId int64, use
|
|||||||
|
|
||||||
// ListEnabledACMETasks 列出单页任务
|
// ListEnabledACMETasks 列出单页任务
|
||||||
func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string, offset int64, size int64) (result []*ACMETask, err error) {
|
func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string, offset int64, size int64) (result []*ACMETask, err error) {
|
||||||
query := dbutils.NewQuery(tx, this, adminId, userId)
|
var query = this.Query(tx)
|
||||||
|
if adminId > 0 {
|
||||||
|
query.Attr("adminId", adminId)
|
||||||
|
}
|
||||||
|
query.Attr("userId", userId) // 这个条件必须加上
|
||||||
if isAvailable || isExpired || expiringDays > 0 {
|
if isAvailable || isExpired || expiringDays > 0 {
|
||||||
query.Gt("certId", 0)
|
query.Gt("certId", 0)
|
||||||
|
|
||||||
@@ -228,7 +236,13 @@ func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId
|
|||||||
|
|
||||||
// CheckACMETask 检查权限
|
// CheckACMETask 检查权限
|
||||||
func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, adminId int64, userId int64, acmeTaskId int64) (bool, error) {
|
func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, adminId int64, userId int64, acmeTaskId int64) (bool, error) {
|
||||||
return dbutils.NewQuery(tx, this, adminId, userId).
|
var query = this.Query(tx)
|
||||||
|
if adminId > 0 {
|
||||||
|
query.Attr("adminId", adminId)
|
||||||
|
}
|
||||||
|
query.Attr("userId", userId) // 这个条件必须加上
|
||||||
|
|
||||||
|
return query.
|
||||||
State(ACMETaskStateEnabled).
|
State(ACMETaskStateEnabled).
|
||||||
Pk(acmeTaskId).
|
Pk(acmeTaskId).
|
||||||
Exist()
|
Exist()
|
||||||
@@ -319,7 +333,7 @@ func (this *ACMETaskDAO) runTaskWithoutLog(tx *dbs.Tx, taskId int64) (isOk bool,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteUser := acmeutils.NewUser(user.Email, privateKey, func(resource *registration.Resource) error {
|
var remoteUser = acmeutils.NewUser(user.Email, privateKey, func(resource *registration.Resource) error {
|
||||||
resourceJSON, err := json.Marshal(resource)
|
resourceJSON, err := json.Marshal(resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -382,7 +396,7 @@ func (this *ACMETaskDAO) runTaskWithoutLog(tx *dbs.Tx, taskId int64) (isOk bool,
|
|||||||
acmeTask.Provider = acmeProvider
|
acmeTask.Provider = acmeProvider
|
||||||
acmeTask.Account = acmeAccount
|
acmeTask.Account = acmeAccount
|
||||||
|
|
||||||
acmeRequest := acmeutils.NewRequest(acmeTask)
|
var acmeRequest = acmeutils.NewRequest(acmeTask)
|
||||||
acmeRequest.OnAuth(func(domain, token, keyAuth string) {
|
acmeRequest.OnAuth(func(domain, token, keyAuth string) {
|
||||||
err := SharedACMEAuthenticationDAO.CreateAuth(tx, taskId, domain, token, keyAuth)
|
err := SharedACMEAuthenticationDAO.CreateAuth(tx, taskId, domain, token, keyAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -398,7 +412,7 @@ func (this *ACMETaskDAO) runTaskWithoutLog(tx *dbs.Tx, taskId int64) (isOk bool,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("ACME", "encode auth data failed: '"+task.AuthURL+"'")
|
remotelogs.Error("ACME", "encode auth data failed: '"+task.AuthURL+"'")
|
||||||
} else {
|
} else {
|
||||||
client := utils.SharedHttpClient(5 * time.Second)
|
var client = utils.SharedHttpClient(10 * time.Second)
|
||||||
req, err := http.NewRequest(http.MethodPost, task.AuthURL, bytes.NewReader(authJSON))
|
req, err := http.NewRequest(http.MethodPost, task.AuthURL, bytes.NewReader(authJSON))
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("User-Agent", teaconst.ProductName+"/"+teaconst.Version)
|
req.Header.Set("User-Agent", teaconst.ProductName+"/"+teaconst.Version)
|
||||||
@@ -423,7 +437,7 @@ func (this *ACMETaskDAO) runTaskWithoutLog(tx *dbs.Tx, taskId int64) (isOk bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 分析证书
|
// 分析证书
|
||||||
sslConfig := &sslconfigs.SSLCertConfig{
|
var sslConfig = &sslconfigs.SSLCertConfig{
|
||||||
CertData: certData,
|
CertData: certData,
|
||||||
KeyData: keyData,
|
KeyData: keyData,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,11 @@ import (
|
|||||||
// CheckClusterDNS 检查集群的DNS问题
|
// CheckClusterDNS 检查集群的DNS问题
|
||||||
// 藏这么深是避免package循环引用的问题
|
// 藏这么深是避免package循环引用的问题
|
||||||
func CheckClusterDNS(tx *dbs.Tx, cluster *models.NodeCluster) (issues []*pb.DNSIssue, err error) {
|
func CheckClusterDNS(tx *dbs.Tx, cluster *models.NodeCluster) (issues []*pb.DNSIssue, err error) {
|
||||||
clusterId := int64(cluster.Id)
|
var clusterId = int64(cluster.Id)
|
||||||
domainId := int64(cluster.DnsDomainId)
|
var domainId = int64(cluster.DnsDomainId)
|
||||||
|
|
||||||
|
// 集群DNS设置
|
||||||
|
var clusterDNSConfig, _ = cluster.DecodeDNSConfig()
|
||||||
|
|
||||||
// 检查域名
|
// 检查域名
|
||||||
domain, err := dns.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, domainId, nil)
|
domain, err := dns.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, domainId, nil)
|
||||||
@@ -101,7 +104,7 @@ func CheckClusterDNS(tx *dbs.Tx, cluster *models.NodeCluster) (issues []*pb.DNSI
|
|||||||
// TODO 检查域名是否已解析
|
// TODO 检查域名是否已解析
|
||||||
|
|
||||||
// 检查节点
|
// 检查节点
|
||||||
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true)
|
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true, clusterDNSConfig != nil && clusterDNSConfig.IncludingLnNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,10 @@ var SharedHTTPAccessLogDAO *HTTPAccessLogDAO
|
|||||||
var (
|
var (
|
||||||
oldAccessLogQueue = make(chan *pb.HTTPAccessLog)
|
oldAccessLogQueue = make(chan *pb.HTTPAccessLog)
|
||||||
accessLogQueue = make(chan *pb.HTTPAccessLog, 10_000)
|
accessLogQueue = make(chan *pb.HTTPAccessLog, 10_000)
|
||||||
accessLogQueueMaxLength = 100_000
|
accessLogQueueMaxLength = 100_000 //队列最大长度
|
||||||
accessLogQueuePercent = 100 // 0-100
|
accessLogQueuePercent = 100 // 0-100
|
||||||
accessLogCountPerSecond = 10_000 // 0 表示不限制
|
accessLogCountPerSecond = 10_000 // 每秒钟写入条数,0 表示不限制
|
||||||
|
accessLogPerTx = 100 // 单事务写入条数
|
||||||
accessLogConfigJSON = []byte{}
|
accessLogConfigJSON = []byte{}
|
||||||
accessLogQueueChanged = make(chan zero.Zero, 1)
|
accessLogQueueChanged = make(chan zero.Zero, 1)
|
||||||
|
|
||||||
@@ -85,10 +86,17 @@ func init() {
|
|||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
var ticker = time.NewTicker(1 * time.Second)
|
var ticker = time.NewTicker(1 * time.Second)
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
var tx *dbs.Tx
|
var countTxs = accessLogCountPerSecond / accessLogPerTx
|
||||||
err := SharedHTTPAccessLogDAO.DumpAccessLogsFromQueue(tx, accessLogCountPerSecond)
|
if countTxs <= 0 {
|
||||||
if err != nil {
|
countTxs = 1
|
||||||
remotelogs.Error("HTTP_ACCESS_LOG_QUEUE", "dump access logs failed: "+err.Error())
|
}
|
||||||
|
for i := 0; i < countTxs; i++ {
|
||||||
|
hasMore, err := SharedHTTPAccessLogDAO.DumpAccessLogsFromQueue(accessLogPerTx)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("HTTP_ACCESS_LOG_QUEUE", "dump access logs failed: "+err.Error())
|
||||||
|
} else if !hasMore {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -132,7 +140,11 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLogs(tx *dbs.Tx, accessLogs []*pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DumpAccessLogsFromQueue 从队列导入访问日志
|
// DumpAccessLogsFromQueue 从队列导入访问日志
|
||||||
func (this *HTTPAccessLogDAO) DumpAccessLogsFromQueue(tx *dbs.Tx, size int) error {
|
func (this *HTTPAccessLogDAO) DumpAccessLogsFromQueue(size int) (hasMore bool, err error) {
|
||||||
|
if size <= 0 {
|
||||||
|
size = 100
|
||||||
|
}
|
||||||
|
|
||||||
var dao = randomHTTPAccessLogDAO()
|
var dao = randomHTTPAccessLogDAO()
|
||||||
if dao == nil {
|
if dao == nil {
|
||||||
dao = &HTTPAccessLogDAOWrapper{
|
dao = &HTTPAccessLogDAOWrapper{
|
||||||
@@ -141,14 +153,25 @@ func (this *HTTPAccessLogDAO) DumpAccessLogsFromQueue(tx *dbs.Tx, size int) erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if size <= 0 {
|
if len(oldAccessLogQueue) == 0 && len(accessLogQueue) == 0 {
|
||||||
size = 1_000_000
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 开始事务
|
||||||
|
tx, err := dao.DAO.Instance.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = tx.Commit()
|
||||||
|
}()
|
||||||
|
|
||||||
// 复制变量,防止中途改变
|
// 复制变量,防止中途改变
|
||||||
var oldQueue = oldAccessLogQueue
|
var oldQueue = oldAccessLogQueue
|
||||||
var newQueue = accessLogQueue
|
var newQueue = accessLogQueue
|
||||||
|
|
||||||
|
hasMore = true
|
||||||
|
|
||||||
Loop:
|
Loop:
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
// old
|
// old
|
||||||
@@ -156,7 +179,7 @@ Loop:
|
|||||||
case accessLog := <-oldQueue:
|
case accessLog := <-oldQueue:
|
||||||
err := this.CreateHTTPAccessLog(tx, dao.DAO, accessLog)
|
err := this.CreateHTTPAccessLog(tx, dao.DAO, accessLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
continue Loop
|
continue Loop
|
||||||
default:
|
default:
|
||||||
@@ -168,15 +191,16 @@ Loop:
|
|||||||
case accessLog := <-newQueue:
|
case accessLog := <-newQueue:
|
||||||
err := this.CreateHTTPAccessLog(tx, dao.DAO, accessLog)
|
err := this.CreateHTTPAccessLog(tx, dao.DAO, accessLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
continue Loop
|
continue Loop
|
||||||
default:
|
default:
|
||||||
|
hasMore = false
|
||||||
break Loop
|
break Loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return hasMore, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateHTTPAccessLog 写入单条访问日志
|
// CreateHTTPAccessLog 写入单条访问日志
|
||||||
@@ -767,6 +791,9 @@ func (this *HTTPAccessLogDAO) SetupQueue() {
|
|||||||
|
|
||||||
accessLogQueuePercent = config.Percent
|
accessLogQueuePercent = config.Percent
|
||||||
accessLogCountPerSecond = config.CountPerSecond
|
accessLogCountPerSecond = config.CountPerSecond
|
||||||
|
if accessLogCountPerSecond <= 0 {
|
||||||
|
accessLogCountPerSecond = 10_000
|
||||||
|
}
|
||||||
if config.MaxLength <= 0 {
|
if config.MaxLength <= 0 {
|
||||||
config.MaxLength = 100_000
|
config.MaxLength = 100_000
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ func TestCreateHTTPAccessLog(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
accessLog := &pb.HTTPAccessLog{
|
var accessLog = &pb.HTTPAccessLog{
|
||||||
ServerId: 1,
|
ServerId: 1,
|
||||||
NodeId: 4,
|
NodeId: 4,
|
||||||
Status: 200,
|
Status: 200,
|
||||||
Timestamp: time.Now().Unix(),
|
Timestamp: time.Now().Unix(),
|
||||||
}
|
}
|
||||||
dao := randomHTTPAccessLogDAO()
|
var dao = randomHTTPAccessLogDAO()
|
||||||
t.Log("dao:", dao)
|
t.Log("dao:", dao)
|
||||||
|
|
||||||
// 先初始化
|
// 先初始化
|
||||||
@@ -37,12 +37,59 @@ func TestCreateHTTPAccessLog(t *testing.T) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
t.Log(time.Since(before).Seconds()*1000, "ms")
|
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
err = SharedHTTPAccessLogDAO.CreateHTTPAccessLog(tx, dao.DAO, accessLog)
|
err = SharedHTTPAccessLogDAO.CreateHTTPAccessLog(tx, dao.DAO, accessLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateHTTPAccessLog_Tx(t *testing.T) {
|
||||||
|
dbs.NotifyReady()
|
||||||
|
|
||||||
|
var tx *dbs.Tx
|
||||||
|
|
||||||
|
err := NewDBNodeInitializer().loop()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var accessLog = &pb.HTTPAccessLog{
|
||||||
|
ServerId: 1,
|
||||||
|
NodeId: 4,
|
||||||
|
Status: 200,
|
||||||
|
Timestamp: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
var dao = randomHTTPAccessLogDAO()
|
||||||
|
t.Log("dao:", dao)
|
||||||
|
|
||||||
|
// 先初始化
|
||||||
|
_ = SharedHTTPAccessLogDAO.CreateHTTPAccessLog(tx, dao.DAO, accessLog)
|
||||||
|
|
||||||
|
var before = time.Now()
|
||||||
|
defer func() {
|
||||||
|
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||||
|
}()
|
||||||
|
|
||||||
|
tx, err = dao.DAO.Instance.Begin()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
err = SharedHTTPAccessLogDAO.CreateHTTPAccessLog(tx, dao.DAO, accessLog)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,9 @@ func (this *HTTPAuthPolicyDAO) FindEnabledHTTPAuthPolicy(tx *dbs.Tx, id int64) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateHTTPAuthPolicy 创建策略
|
// CreateHTTPAuthPolicy 创建策略
|
||||||
func (this *HTTPAuthPolicyDAO) CreateHTTPAuthPolicy(tx *dbs.Tx, name string, methodType string, paramsJSON []byte) (int64, error) {
|
func (this *HTTPAuthPolicyDAO) CreateHTTPAuthPolicy(tx *dbs.Tx, userId int64, name string, methodType string, paramsJSON []byte) (int64, error) {
|
||||||
var op = NewHTTPAuthPolicyOperator()
|
var op = NewHTTPAuthPolicyOperator()
|
||||||
|
op.UserId = userId
|
||||||
op.Name = name
|
op.Name = name
|
||||||
op.Type = methodType
|
op.Type = methodType
|
||||||
op.Params = paramsJSON
|
op.Params = paramsJSON
|
||||||
@@ -137,6 +138,20 @@ func (this *HTTPAuthPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, c
|
|||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckUserPolicy 检查用户权限
|
||||||
|
func (this *HTTPAuthPolicyDAO) CheckUserPolicy(tx *dbs.Tx, userId int64, policyId int64) error {
|
||||||
|
if userId <= 0 || policyId <= 0 {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithHTTPAuthPolicyId(tx, policyId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return SharedHTTPWebDAO.CheckUserWeb(tx, userId, webId)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更改
|
// NotifyUpdate 通知更改
|
||||||
func (this *HTTPAuthPolicyDAO) NotifyUpdate(tx *dbs.Tx, policyId int64) error {
|
func (this *HTTPAuthPolicyDAO) NotifyUpdate(tx *dbs.Tx, policyId int64) error {
|
||||||
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithHTTPAuthPolicyId(tx, policyId)
|
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithHTTPAuthPolicyId(tx, policyId)
|
||||||
|
|||||||
@@ -1042,6 +1042,10 @@ func (this *HTTPWebDAO) FindWebServerGroupId(tx *dbs.Tx, webId int64) (groupId i
|
|||||||
|
|
||||||
// CheckUserWeb 检查用户权限
|
// CheckUserWeb 检查用户权限
|
||||||
func (this *HTTPWebDAO) CheckUserWeb(tx *dbs.Tx, userId int64, webId int64) error {
|
func (this *HTTPWebDAO) CheckUserWeb(tx *dbs.Tx, userId int64, webId int64) error {
|
||||||
|
if userId <= 0 || webId <= 0 {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
serverId, err := this.FindWebServerId(tx, webId)
|
serverId, err := this.FindWebServerId(tx, webId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
140
internal/db/models/ip_library_artifact_dao.go
Normal file
140
internal/db/models/ip_library_artifact_dao.go
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
IPLibraryArtifactStateEnabled = 1 // 已启用
|
||||||
|
IPLibraryArtifactStateDisabled = 0 // 已禁用
|
||||||
|
)
|
||||||
|
|
||||||
|
type IPLibraryArtifactDAO dbs.DAO
|
||||||
|
|
||||||
|
func NewIPLibraryArtifactDAO() *IPLibraryArtifactDAO {
|
||||||
|
return dbs.NewDAO(&IPLibraryArtifactDAO{
|
||||||
|
DAOObject: dbs.DAOObject{
|
||||||
|
DB: Tea.Env,
|
||||||
|
Table: "edgeIPLibraryArtifacts",
|
||||||
|
Model: new(IPLibraryArtifact),
|
||||||
|
PkName: "id",
|
||||||
|
},
|
||||||
|
}).(*IPLibraryArtifactDAO)
|
||||||
|
}
|
||||||
|
|
||||||
|
var SharedIPLibraryArtifactDAO *IPLibraryArtifactDAO
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
dbs.OnReady(func() {
|
||||||
|
SharedIPLibraryArtifactDAO = NewIPLibraryArtifactDAO()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableIPLibraryArtifact 启用条目
|
||||||
|
func (this *IPLibraryArtifactDAO) EnableIPLibraryArtifact(tx *dbs.Tx, id int64) error {
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Set("state", IPLibraryArtifactStateEnabled).
|
||||||
|
Update()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableIPLibraryArtifact 禁用条目
|
||||||
|
func (this *IPLibraryArtifactDAO) DisableIPLibraryArtifact(tx *dbs.Tx, id int64) error {
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Set("state", IPLibraryArtifactStateDisabled).
|
||||||
|
Update()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindEnabledIPLibraryArtifact 查找启用中的条目
|
||||||
|
func (this *IPLibraryArtifactDAO) FindEnabledIPLibraryArtifact(tx *dbs.Tx, id int64) (*IPLibraryArtifact, error) {
|
||||||
|
result, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
State(IPLibraryArtifactStateEnabled).
|
||||||
|
Find()
|
||||||
|
if result == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result.(*IPLibraryArtifact), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateArtifact 创建制品
|
||||||
|
func (this *IPLibraryArtifactDAO) CreateArtifact(tx *dbs.Tx, name string, fileId int64, libraryFileId int64, meta *iplibrary.Meta) (int64, error) {
|
||||||
|
var op = NewIPLibraryArtifactOperator()
|
||||||
|
op.Name = name
|
||||||
|
op.FileId = fileId
|
||||||
|
op.LibraryFileId = libraryFileId
|
||||||
|
|
||||||
|
metaJSON, err := json.Marshal(meta)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.Meta = metaJSON
|
||||||
|
op.State = IPLibraryArtifactStateEnabled
|
||||||
|
|
||||||
|
var code = stringutil.Md5(utils.Sha1RandomString())[:8]
|
||||||
|
meta.Code = code
|
||||||
|
op.Code = code // 要比较短,方便识别
|
||||||
|
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllArtifacts 查找制品列表
|
||||||
|
func (this *IPLibraryArtifactDAO) FindAllArtifacts(tx *dbs.Tx) (result []*IPLibraryArtifact, err error) {
|
||||||
|
_, err = this.Query(tx).
|
||||||
|
State(IPLibraryArtifactStateEnabled).
|
||||||
|
DescPk().
|
||||||
|
Slice(&result).
|
||||||
|
FindAll()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindPublicArtifact 查找当前使用的制品
|
||||||
|
func (this *IPLibraryArtifactDAO) FindPublicArtifact(tx *dbs.Tx) (*IPLibraryArtifact, error) {
|
||||||
|
one, err := this.Query(tx).
|
||||||
|
State(IPLibraryArtifactStateEnabled).
|
||||||
|
Attr("isPublic", true).
|
||||||
|
Result("id", "fileId", "code").
|
||||||
|
Find()
|
||||||
|
if err != nil || one == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return one.(*IPLibraryArtifact), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateArtifactPublic 使用某个制品
|
||||||
|
func (this *IPLibraryArtifactDAO) UpdateArtifactPublic(tx *dbs.Tx, artifactId int64, isPublic bool) error {
|
||||||
|
// 取消使用
|
||||||
|
if !isPublic {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(artifactId).
|
||||||
|
Set("isPublic", false).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用
|
||||||
|
|
||||||
|
// 先取消别的
|
||||||
|
err := this.Query(tx).
|
||||||
|
Neq("id", artifactId).
|
||||||
|
State(IPLibraryArtifactStateEnabled).
|
||||||
|
Attr("isPublic", true).
|
||||||
|
Set("isPublic", false).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(artifactId).
|
||||||
|
Set("isPublic", true).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
6
internal/db/models/ip_library_artifact_dao_test.go
Normal file
6
internal/db/models/ip_library_artifact_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package models_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
)
|
||||||
32
internal/db/models/ip_library_artifact_model.go
Normal file
32
internal/db/models/ip_library_artifact_model.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
// IPLibraryArtifact IP库制品
|
||||||
|
type IPLibraryArtifact struct {
|
||||||
|
Id uint32 `field:"id"` // ID
|
||||||
|
Name string `field:"name"` // 名称
|
||||||
|
FileId uint64 `field:"fileId"` // 文件ID
|
||||||
|
LibraryFileId uint32 `field:"libraryFileId"` // IP库文件ID
|
||||||
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
|
Meta dbs.JSON `field:"meta"` // 元数据
|
||||||
|
IsPublic bool `field:"isPublic"` // 是否为公用
|
||||||
|
Code string `field:"code"` // 代号
|
||||||
|
State uint8 `field:"state"` // 状态
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPLibraryArtifactOperator struct {
|
||||||
|
Id any // ID
|
||||||
|
Name any // 名称
|
||||||
|
FileId any // 文件ID
|
||||||
|
LibraryFileId any // IP库文件ID
|
||||||
|
CreatedAt any // 创建时间
|
||||||
|
Meta any // 元数据
|
||||||
|
IsPublic any // 是否为公用
|
||||||
|
Code any // 代号
|
||||||
|
State any // 状态
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIPLibraryArtifactOperator() *IPLibraryArtifactOperator {
|
||||||
|
return &IPLibraryArtifactOperator{}
|
||||||
|
}
|
||||||
1
internal/db/models/ip_library_artifact_model_ext.go
Normal file
1
internal/db/models/ip_library_artifact_model_ext.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package models
|
||||||
@@ -72,8 +72,9 @@ func (this *IPLibraryFileDAO) FindEnabledIPLibraryFile(tx *dbs.Tx, id int64) (*I
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateLibraryFile 创建文件
|
// CreateLibraryFile 创建文件
|
||||||
func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, template string, emptyValues []string, fileId int64, countries []string, provinces [][2]string, cities [][3]string, towns [][4]string, providers []string) (int64, error) {
|
func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, name string, template string, emptyValues []string, fileId int64, countries []string, provinces [][2]string, cities [][3]string, towns [][4]string, providers []string) (int64, error) {
|
||||||
var op = NewIPLibraryFileOperator()
|
var op = NewIPLibraryFileOperator()
|
||||||
|
op.Name = name
|
||||||
op.Template = template
|
op.Template = template
|
||||||
|
|
||||||
if emptyValues == nil {
|
if emptyValues == nil {
|
||||||
@@ -137,6 +138,18 @@ func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, template string, emp
|
|||||||
return this.SaveInt64(tx, op)
|
return this.SaveInt64(tx, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAllFinishedLibraryFiles 查找所有已完成的文件
|
||||||
|
func (this *IPLibraryFileDAO) FindAllFinishedLibraryFiles(tx *dbs.Tx) (result []*IPLibraryFile, err error) {
|
||||||
|
_, err = this.Query(tx).
|
||||||
|
State(IPLibraryFileStateEnabled).
|
||||||
|
Result("id", "fileId", "createdAt", "generatedFileId", "generatedAt", "name"). // 这里不需要其他信息
|
||||||
|
Attr("isFinished", true).
|
||||||
|
DescPk().
|
||||||
|
Slice(&result).
|
||||||
|
FindAll()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// FindAllUnfinishedLibraryFiles 查找所有未完成的文件
|
// FindAllUnfinishedLibraryFiles 查找所有未完成的文件
|
||||||
func (this *IPLibraryFileDAO) FindAllUnfinishedLibraryFiles(tx *dbs.Tx) (result []*IPLibraryFile, err error) {
|
func (this *IPLibraryFileDAO) FindAllUnfinishedLibraryFiles(tx *dbs.Tx) (result []*IPLibraryFile, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
@@ -324,7 +337,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var countries = []*iplibrary.Country{}
|
var countries = []*iplibrary.Country{}
|
||||||
for _, country := range dbCountries {
|
for _, country := range dbCountries {
|
||||||
countries = append(countries, &iplibrary.Country{
|
countries = append(countries, &iplibrary.Country{
|
||||||
Id: int64(country.Id),
|
Id: country.Id,
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
Codes: country.AllCodes(),
|
Codes: country.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -339,7 +352,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var provinces = []*iplibrary.Province{}
|
var provinces = []*iplibrary.Province{}
|
||||||
for _, province := range dbProvinces {
|
for _, province := range dbProvinces {
|
||||||
provinces = append(provinces, &iplibrary.Province{
|
provinces = append(provinces, &iplibrary.Province{
|
||||||
Id: int64(province.Id),
|
Id: province.Id,
|
||||||
Name: province.DisplayName(),
|
Name: province.DisplayName(),
|
||||||
Codes: province.AllCodes(),
|
Codes: province.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -354,7 +367,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var cities = []*iplibrary.City{}
|
var cities = []*iplibrary.City{}
|
||||||
for _, city := range dbCities {
|
for _, city := range dbCities {
|
||||||
cities = append(cities, &iplibrary.City{
|
cities = append(cities, &iplibrary.City{
|
||||||
Id: int64(city.Id),
|
Id: city.Id,
|
||||||
Name: city.DisplayName(),
|
Name: city.DisplayName(),
|
||||||
Codes: city.AllCodes(),
|
Codes: city.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -369,7 +382,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var towns = []*iplibrary.Town{}
|
var towns = []*iplibrary.Town{}
|
||||||
for _, town := range dbTowns {
|
for _, town := range dbTowns {
|
||||||
towns = append(towns, &iplibrary.Town{
|
towns = append(towns, &iplibrary.Town{
|
||||||
Id: int64(town.Id),
|
Id: town.Id,
|
||||||
Name: town.DisplayName(),
|
Name: town.DisplayName(),
|
||||||
Codes: town.AllCodes(),
|
Codes: town.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -384,7 +397,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var providers = []*iplibrary.Provider{}
|
var providers = []*iplibrary.Provider{}
|
||||||
for _, provider := range dbProviders {
|
for _, provider := range dbProviders {
|
||||||
providers = append(providers, &iplibrary.Provider{
|
providers = append(providers, &iplibrary.Provider{
|
||||||
Id: int64(provider.Id),
|
Id: provider.Id,
|
||||||
Name: provider.DisplayName(),
|
Name: provider.DisplayName(),
|
||||||
Codes: provider.AllCodes(),
|
Codes: provider.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -392,7 +405,7 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
|
|
||||||
var libraryCode = utils.Sha1RandomString() // 每次都生成新的code
|
var libraryCode = utils.Sha1RandomString() // 每次都生成新的code
|
||||||
var filePath = dir + "/" + this.composeFilename(libraryFileId, libraryCode)
|
var filePath = dir + "/" + this.composeFilename(libraryFileId, libraryCode)
|
||||||
writer, err := iplibrary.NewFileWriter(filePath, &iplibrary.Meta{
|
var meta = &iplibrary.Meta{
|
||||||
Author: "", // 将来用户可以自行填写
|
Author: "", // 将来用户可以自行填写
|
||||||
CreatedAt: time.Now().Unix(),
|
CreatedAt: time.Now().Unix(),
|
||||||
Countries: countries,
|
Countries: countries,
|
||||||
@@ -400,13 +413,15 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
Cities: cities,
|
Cities: cities,
|
||||||
Towns: towns,
|
Towns: towns,
|
||||||
Providers: providers,
|
Providers: providers,
|
||||||
})
|
}
|
||||||
|
writer, err := iplibrary.NewFileWriter(filePath, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = writer.Close()
|
_ = writer.Close()
|
||||||
|
_ = os.Remove(filePath)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = writer.WriteMeta()
|
err = writer.WriteMeta()
|
||||||
@@ -563,6 +578,12 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加制品
|
||||||
|
_, err = SharedIPLibraryArtifactDAO.CreateArtifact(tx, libraryFile.Name, generatedFileId, libraryFileId, meta)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func TestIPLibraryFileDAO_GenerateIPLibrary(t *testing.T) {
|
|||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
|
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
err := models.SharedIPLibraryFileDAO.GenerateIPLibrary(tx, 3)
|
err := models.SharedIPLibraryFileDAO.GenerateIPLibrary(tx, 4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import "github.com/iwind/TeaGo/dbs"
|
|||||||
// IPLibraryFile IP库上传的文件
|
// IPLibraryFile IP库上传的文件
|
||||||
type IPLibraryFile struct {
|
type IPLibraryFile struct {
|
||||||
Id uint64 `field:"id"` // ID
|
Id uint64 `field:"id"` // ID
|
||||||
|
Name string `field:"name"` // IP库名称
|
||||||
FileId uint64 `field:"fileId"` // 原始文件ID
|
FileId uint64 `field:"fileId"` // 原始文件ID
|
||||||
Template string `field:"template"` // 模板
|
Template string `field:"template"` // 模板
|
||||||
EmptyValues dbs.JSON `field:"emptyValues"` // 空值列表
|
EmptyValues dbs.JSON `field:"emptyValues"` // 空值列表
|
||||||
@@ -23,6 +24,7 @@ type IPLibraryFile struct {
|
|||||||
|
|
||||||
type IPLibraryFileOperator struct {
|
type IPLibraryFileOperator struct {
|
||||||
Id any // ID
|
Id any // ID
|
||||||
|
Name any // IP库名称
|
||||||
FileId any // 原始文件ID
|
FileId any // 原始文件ID
|
||||||
Template any // 模板
|
Template any // 模板
|
||||||
EmptyValues any // 空值列表
|
EmptyValues any // 空值列表
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package models
|
|||||||
import (
|
import (
|
||||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -38,7 +39,7 @@ func init() {
|
|||||||
func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level string, description string, action string, ip string) error {
|
func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level string, description string, action string, ip string) error {
|
||||||
var op = NewLogOperator()
|
var op = NewLogOperator()
|
||||||
op.Level = level
|
op.Level = level
|
||||||
op.Description = description
|
op.Description = utils.LimitString(description, 1000)
|
||||||
op.Action = action
|
op.Action = action
|
||||||
op.Ip = ip
|
op.Ip = ip
|
||||||
op.Type = adminType
|
op.Type = adminType
|
||||||
|
|||||||
@@ -147,11 +147,12 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
|
|||||||
op.DnsDomainId = dnsDomainId
|
op.DnsDomainId = dnsDomainId
|
||||||
op.DnsName = dnsName
|
op.DnsName = dnsName
|
||||||
var dnsConfig = &dnsconfigs.ClusterDNSConfig{
|
var dnsConfig = &dnsconfigs.ClusterDNSConfig{
|
||||||
NodesAutoSync: true,
|
NodesAutoSync: true,
|
||||||
ServersAutoSync: true,
|
ServersAutoSync: true,
|
||||||
CNameRecords: []string{},
|
CNameRecords: []string{},
|
||||||
CNameAsDomain: true,
|
CNameAsDomain: true,
|
||||||
TTL: 0,
|
TTL: 0,
|
||||||
|
IncludingLnNodes: true,
|
||||||
}
|
}
|
||||||
dnsJSON, err := json.Marshal(dnsConfig)
|
dnsJSON, err := json.Marshal(dnsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -468,7 +469,7 @@ func (this *NodeClusterDAO) ExistClusterDNSName(tx *dbs.Tx, dnsName string, excl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateClusterDNS 修改集群DNS相关信息
|
// UpdateClusterDNS 修改集群DNS相关信息
|
||||||
func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsName string, dnsDomainId int64, nodesAutoSync bool, serversAutoSync bool, cnameRecords []string, ttl int32, cnameAsDomain bool) error {
|
func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsName string, dnsDomainId int64, nodesAutoSync bool, serversAutoSync bool, cnameRecords []string, ttl int32, cnameAsDomain bool, includingLnNodes bool) error {
|
||||||
if clusterId <= 0 {
|
if clusterId <= 0 {
|
||||||
return errors.New("invalid clusterId")
|
return errors.New("invalid clusterId")
|
||||||
}
|
}
|
||||||
@@ -504,11 +505,12 @@ func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsNam
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dnsConfig = &dnsconfigs.ClusterDNSConfig{
|
var dnsConfig = &dnsconfigs.ClusterDNSConfig{
|
||||||
NodesAutoSync: nodesAutoSync,
|
NodesAutoSync: nodesAutoSync,
|
||||||
ServersAutoSync: serversAutoSync,
|
ServersAutoSync: serversAutoSync,
|
||||||
CNameRecords: cnameRecords,
|
CNameRecords: cnameRecords,
|
||||||
TTL: ttl,
|
TTL: ttl,
|
||||||
CNameAsDomain: cnameAsDomain,
|
CNameAsDomain: cnameAsDomain,
|
||||||
|
IncludingLnNodes: includingLnNodes,
|
||||||
}
|
}
|
||||||
dnsJSON, err := json.Marshal(dnsConfig)
|
dnsJSON, err := json.Marshal(dnsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1066,7 +1068,7 @@ func (this *NodeClusterDAO) FindClusterDDoSProtection(tx *dbs.Tx, clusterId int6
|
|||||||
return one.(*NodeCluster).DecodeDDoSProtection(), nil
|
return one.(*NodeCluster).DecodeDDoSProtection(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateClusterDDoSProtection 设置集群的DDOS设置
|
// UpdateClusterDDoSProtection 设置集群的DDoS设置
|
||||||
func (this *NodeClusterDAO) UpdateClusterDDoSProtection(tx *dbs.Tx, clusterId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
|
func (this *NodeClusterDAO) UpdateClusterDDoSProtection(tx *dbs.Tx, clusterId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
|
||||||
if clusterId <= 0 {
|
if clusterId <= 0 {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
|
|||||||
@@ -11,13 +11,15 @@ func (this *NodeCluster) DecodeDNSConfig() (*dnsconfigs.ClusterDNSConfig, error)
|
|||||||
if len(this.Dns) == 0 {
|
if len(this.Dns) == 0 {
|
||||||
// 一定要返回一个默认的值,防止产生nil
|
// 一定要返回一个默认的值,防止产生nil
|
||||||
return &dnsconfigs.ClusterDNSConfig{
|
return &dnsconfigs.ClusterDNSConfig{
|
||||||
NodesAutoSync: false,
|
NodesAutoSync: false,
|
||||||
ServersAutoSync: false,
|
ServersAutoSync: false,
|
||||||
CNameAsDomain: true,
|
CNameAsDomain: true,
|
||||||
|
IncludingLnNodes: true,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
var dnsConfig = &dnsconfigs.ClusterDNSConfig{
|
var dnsConfig = &dnsconfigs.ClusterDNSConfig{
|
||||||
CNameAsDomain: true,
|
CNameAsDomain: true,
|
||||||
|
IncludingLnNodes: true,
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(this.Dns, &dnsConfig)
|
err := json.Unmarshal(this.Dns, &dnsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ func (this *NodeDAO) CreateNode(tx *dbs.Tx, adminId int64, name string, clusterI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNode 修改节点
|
// UpdateNode 修改节点
|
||||||
func (this *NodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, clusterId int64, secondaryClusterIds []int64, groupId int64, regionId int64, isOn bool, level int) error {
|
func (this *NodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, clusterId int64, secondaryClusterIds []int64, groupId int64, regionId int64, isOn bool, level int, lnAddrs []string) error {
|
||||||
if nodeId <= 0 {
|
if nodeId <= 0 {
|
||||||
return errors.New("invalid nodeId")
|
return errors.New("invalid nodeId")
|
||||||
}
|
}
|
||||||
@@ -248,6 +248,15 @@ func (this *NodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, clusterId
|
|||||||
|
|
||||||
if teaconst.IsPlus {
|
if teaconst.IsPlus {
|
||||||
op.Level = level
|
op.Level = level
|
||||||
|
|
||||||
|
if lnAddrs == nil {
|
||||||
|
lnAddrs = []string{}
|
||||||
|
}
|
||||||
|
lnAddrsJSON, err := json.Marshal(lnAddrs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.LnAddrs = lnAddrsJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
@@ -605,7 +614,7 @@ func (this *NodeDAO) FindEnabledNodesWithGroupIdAndLevel(tx *dbs.Tx, groupId int
|
|||||||
}
|
}
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(NodeStateEnabled).
|
State(NodeStateEnabled).
|
||||||
Result("id", "clusterId", "secondaryClusterIds", "uniqueId", "secret").
|
Result("id", "clusterId", "secondaryClusterIds", "uniqueId", "secret", "lnAddrs").
|
||||||
Attr("isOn", true).
|
Attr("isOn", true).
|
||||||
Attr("groupId", groupId).
|
Attr("groupId", groupId).
|
||||||
Attr("level", level).
|
Attr("level", level).
|
||||||
@@ -1403,7 +1412,7 @@ func (this *NodeDAO) CountAllEnabledNodesWithRegionId(tx *dbs.Tx, regionId int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledNodesDNSWithClusterId 获取一个集群的节点DNS信息
|
// FindAllEnabledNodesDNSWithClusterId 获取一个集群的节点DNS信息
|
||||||
func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(tx *dbs.Tx, clusterId int64, includeSecondaryNodes bool) (result []*Node, err error) {
|
func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(tx *dbs.Tx, clusterId int64, includeSecondaryNodes bool, includingLnNodes bool) (result []*Node, err error) {
|
||||||
if clusterId <= 0 {
|
if clusterId <= 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -1415,6 +1424,9 @@ func (this *NodeDAO) FindAllEnabledNodesDNSWithClusterId(tx *dbs.Tx, clusterId i
|
|||||||
} else {
|
} else {
|
||||||
query.Attr("clusterId", clusterId)
|
query.Attr("clusterId", clusterId)
|
||||||
}
|
}
|
||||||
|
if !includingLnNodes {
|
||||||
|
query.Lte("level", 1)
|
||||||
|
}
|
||||||
_, err = query.
|
_, err = query.
|
||||||
State(NodeStateEnabled).
|
State(NodeStateEnabled).
|
||||||
Attr("isOn", true).
|
Attr("isOn", true).
|
||||||
@@ -1878,14 +1890,18 @@ func (this *NodeDAO) FindParentNodeConfigs(tx *dbs.Tx, nodeId int64, groupId int
|
|||||||
|
|
||||||
if len(parentNodes) > 0 {
|
if len(parentNodes) > 0 {
|
||||||
for _, node := range parentNodes {
|
for _, node := range parentNodes {
|
||||||
addrs, err := SharedNodeIPAddressDAO.FindNodeAccessAndUpIPAddresses(tx, int64(node.Id), nodeconfigs.NodeRoleNode)
|
// 是否有Ln地址
|
||||||
if err != nil {
|
var addrStrings = node.DecodeLnAddrs()
|
||||||
return nil, err
|
if len(addrStrings) == 0 {
|
||||||
}
|
// 如果没有就取节点的可访问地址
|
||||||
var addrStrings = []string{}
|
addrs, err := SharedNodeIPAddressDAO.FindNodeAccessAndUpIPAddresses(tx, int64(node.Id), nodeconfigs.NodeRoleNode)
|
||||||
for _, addr := range addrs {
|
if err != nil {
|
||||||
if addr.IsOn {
|
return nil, err
|
||||||
addrStrings = append(addrStrings, addr.DNSIP())
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if addr.IsOn {
|
||||||
|
addrStrings = append(addrStrings, addr.DNSIP())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1924,7 +1940,7 @@ func (this *NodeDAO) FindNodeDDoSProtection(tx *dbs.Tx, nodeId int64) (*ddosconf
|
|||||||
return one.(*Node).DecodeDDoSProtection(), nil
|
return one.(*Node).DecodeDDoSProtection(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNodeDDoSProtection 设置集群的DDOS设置
|
// UpdateNodeDDoSProtection 设置集群的DDoS设置
|
||||||
func (this *NodeDAO) UpdateNodeDDoSProtection(tx *dbs.Tx, nodeId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
|
func (this *NodeDAO) UpdateNodeDDoSProtection(tx *dbs.Tx, nodeId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
|
||||||
if nodeId <= 0 {
|
if nodeId <= 0 {
|
||||||
return ErrNotFound
|
return ErrNotFound
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
@@ -43,6 +44,8 @@ func init() {
|
|||||||
|
|
||||||
// CreateLog 创建日志
|
// CreateLog 创建日志
|
||||||
func (this *NodeLogDAO) CreateLog(tx *dbs.Tx, nodeRole nodeconfigs.NodeRole, nodeId int64, serverId int64, originId int64, level string, tag string, description string, createdAt int64, logType string, paramsJSON []byte) error {
|
func (this *NodeLogDAO) CreateLog(tx *dbs.Tx, nodeRole nodeconfigs.NodeRole, nodeId int64, serverId int64, originId int64, level string, tag string, description string, createdAt int64, logType string, paramsJSON []byte) error {
|
||||||
|
description = utils.LimitString(description, 1000)
|
||||||
|
|
||||||
// 修复以前同样的日志
|
// 修复以前同样的日志
|
||||||
if nodeId > 0 && level == "success" && len(logType) > 0 && len(paramsJSON) > 0 {
|
if nodeId > 0 && level == "success" && len(logType) > 0 && len(paramsJSON) > 0 {
|
||||||
err := this.Query(tx).
|
err := this.Query(tx).
|
||||||
@@ -339,8 +342,8 @@ func (this *NodeLogDAO) CountAllUnreadNodeLogs(tx *dbs.Tx) (int64, error) {
|
|||||||
Count()
|
Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNodeLogsRead 设置日志为已读
|
// UpdateNodeLogIdsRead 设置一组日志为已读
|
||||||
func (this *NodeLogDAO) UpdateNodeLogsRead(tx *dbs.Tx, nodeLogIds []int64) error {
|
func (this *NodeLogDAO) UpdateNodeLogIdsRead(tx *dbs.Tx, nodeLogIds []int64) error {
|
||||||
for _, logId := range nodeLogIds {
|
for _, logId := range nodeLogIds {
|
||||||
err := this.Query(tx).
|
err := this.Query(tx).
|
||||||
Pk(logId).
|
Pk(logId).
|
||||||
@@ -353,6 +356,16 @@ func (this *NodeLogDAO) UpdateNodeLogsRead(tx *dbs.Tx, nodeLogIds []int64) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateNodeLogsRead 设置节点日志为已读
|
||||||
|
func (this *NodeLogDAO) UpdateNodeLogsRead(tx *dbs.Tx, role nodeconfigs.NodeRole, nodeId int64) error {
|
||||||
|
return this.Query(tx).
|
||||||
|
Attr("role", role).
|
||||||
|
Attr("nodeId", nodeId).
|
||||||
|
Attr("isRead", false).
|
||||||
|
Set("isRead", true).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateAllNodeLogsRead 设置所有日志为已读
|
// UpdateAllNodeLogsRead 设置所有日志为已读
|
||||||
func (this *NodeLogDAO) UpdateAllNodeLogsRead(tx *dbs.Tx) error {
|
func (this *NodeLogDAO) UpdateAllNodeLogsRead(tx *dbs.Tx) error {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ type Node struct {
|
|||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
UserId uint32 `field:"userId"` // 用户ID
|
UserId uint32 `field:"userId"` // 用户ID
|
||||||
Level uint8 `field:"level"` // 级别
|
Level uint8 `field:"level"` // 级别
|
||||||
|
LnAddrs dbs.JSON `field:"lnAddrs"` // Ln级别访问地址
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
IsUp bool `field:"isUp"` // 是否在线
|
IsUp bool `field:"isUp"` // 是否在线
|
||||||
CountUp uint32 `field:"countUp"` // 连续在线次数
|
CountUp uint32 `field:"countUp"` // 连续在线次数
|
||||||
@@ -42,41 +43,42 @@ type Node struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NodeOperator struct {
|
type NodeOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
Level interface{} // 级别
|
Level any // 级别
|
||||||
IsOn interface{} // 是否启用
|
LnAddrs any // Ln级别访问地址
|
||||||
IsUp interface{} // 是否在线
|
IsOn any // 是否启用
|
||||||
CountUp interface{} // 连续在线次数
|
IsUp any // 是否在线
|
||||||
CountDown interface{} // 连续下线次数
|
CountUp any // 连续在线次数
|
||||||
IsActive interface{} // 是否活跃
|
CountDown any // 连续下线次数
|
||||||
InactiveNotifiedAt interface{} // 离线通知时间
|
IsActive any // 是否活跃
|
||||||
UniqueId interface{} // 节点ID
|
InactiveNotifiedAt any // 离线通知时间
|
||||||
Secret interface{} // 密钥
|
UniqueId any // 节点ID
|
||||||
Name interface{} // 节点名
|
Secret any // 密钥
|
||||||
Code interface{} // 代号
|
Name any // 节点名
|
||||||
ClusterId interface{} // 主集群ID
|
Code any // 代号
|
||||||
SecondaryClusterIds interface{} // 从集群ID
|
ClusterId any // 主集群ID
|
||||||
RegionId interface{} // 区域ID
|
SecondaryClusterIds any // 从集群ID
|
||||||
GroupId interface{} // 分组ID
|
RegionId any // 区域ID
|
||||||
CreatedAt interface{} // 创建时间
|
GroupId any // 分组ID
|
||||||
Status interface{} // 最新的状态
|
CreatedAt any // 创建时间
|
||||||
Version interface{} // 当前版本号
|
Status any // 最新的状态
|
||||||
LatestVersion interface{} // 最后版本号
|
Version any // 当前版本号
|
||||||
InstallDir interface{} // 安装目录
|
LatestVersion any // 最后版本号
|
||||||
IsInstalled interface{} // 是否已安装
|
InstallDir any // 安装目录
|
||||||
InstallStatus interface{} // 安装状态
|
IsInstalled any // 是否已安装
|
||||||
State interface{} // 状态
|
InstallStatus any // 安装状态
|
||||||
ConnectedAPINodes interface{} // 当前连接的API节点
|
State any // 状态
|
||||||
MaxCPU interface{} // 可以使用的最多CPU
|
ConnectedAPINodes any // 当前连接的API节点
|
||||||
MaxThreads interface{} // 最大线程数
|
MaxCPU any // 可以使用的最多CPU
|
||||||
DdosProtection interface{} // DDOS配置
|
MaxThreads any // 最大线程数
|
||||||
DnsRoutes interface{} // DNS线路设置
|
DdosProtection any // DDOS配置
|
||||||
MaxCacheDiskCapacity interface{} // 硬盘缓存容量
|
DnsRoutes any // DNS线路设置
|
||||||
MaxCacheMemoryCapacity interface{} // 内存缓存容量
|
MaxCacheDiskCapacity any // 硬盘缓存容量
|
||||||
CacheDiskDir interface{} // 缓存目录
|
MaxCacheMemoryCapacity any // 内存缓存容量
|
||||||
DnsResolver interface{} // DNS解析器
|
CacheDiskDir any // 缓存目录
|
||||||
|
DnsResolver any // DNS解析器
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNodeOperator() *NodeOperator {
|
func NewNodeOperator() *NodeOperator {
|
||||||
|
|||||||
@@ -168,3 +168,16 @@ func (this *Node) DecodeDNSResolver() *nodeconfigs.DNSResolverConfig {
|
|||||||
}
|
}
|
||||||
return resolverConfig
|
return resolverConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Node) DecodeLnAddrs() []string {
|
||||||
|
if IsNull(this.LnAddrs) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = []string{}
|
||||||
|
err := json.Unmarshal(this.LnAddrs, &result)
|
||||||
|
if err != nil {
|
||||||
|
// ignore error
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,11 +23,12 @@ const (
|
|||||||
|
|
||||||
// NS相关
|
// NS相关
|
||||||
|
|
||||||
NSNodeTaskTypeConfigChanged NodeTaskType = "nsConfigChanged"
|
NSNodeTaskTypeConfigChanged NodeTaskType = "nsConfigChanged"
|
||||||
NSNodeTaskTypeDomainChanged NodeTaskType = "nsDomainChanged"
|
NSNodeTaskTypeDomainChanged NodeTaskType = "nsDomainChanged"
|
||||||
NSNodeTaskTypeRecordChanged NodeTaskType = "nsRecordChanged"
|
NSNodeTaskTypeRecordChanged NodeTaskType = "nsRecordChanged"
|
||||||
NSNodeTaskTypeRouteChanged NodeTaskType = "nsRouteChanged"
|
NSNodeTaskTypeRouteChanged NodeTaskType = "nsRouteChanged"
|
||||||
NSNodeTaskTypeKeyChanged NodeTaskType = "nsKeyChanged"
|
NSNodeTaskTypeKeyChanged NodeTaskType = "nsKeyChanged"
|
||||||
|
NSNodeTaskTypeDDosProtectionChanged NodeTaskType = "nsDDoSProtectionChanged" // 节点DDoS配置变更
|
||||||
)
|
)
|
||||||
|
|
||||||
type NodeTaskDAO dbs.DAO
|
type NodeTaskDAO dbs.DAO
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -325,6 +326,45 @@ func (this *NSClusterDAO) CountAllClustersWithSSLPolicyIds(tx *dbs.Tx, sslPolicy
|
|||||||
Count()
|
Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindClusterDDoSProtection 获取集群的DDoS设置
|
||||||
|
func (this *NSClusterDAO) FindClusterDDoSProtection(tx *dbs.Tx, clusterId int64) (*ddosconfigs.ProtectionConfig, error) {
|
||||||
|
one, err := this.Query(tx).
|
||||||
|
Result("ddosProtection").
|
||||||
|
Pk(clusterId).
|
||||||
|
Find()
|
||||||
|
if one == nil || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return one.(*NSCluster).DecodeDDoSProtection(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateClusterDDoSProtection 设置集群的DDoS设置
|
||||||
|
func (this *NSClusterDAO) UpdateClusterDDoSProtection(tx *dbs.Tx, clusterId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
|
||||||
|
if clusterId <= 0 {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
var op = NewNSClusterOperator()
|
||||||
|
op.Id = clusterId
|
||||||
|
|
||||||
|
if ddosProtection == nil {
|
||||||
|
op.DdosProtection = "{}"
|
||||||
|
} else {
|
||||||
|
ddosProtectionJSON, err := json.Marshal(ddosProtection)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.DdosProtection = ddosProtectionJSON
|
||||||
|
}
|
||||||
|
|
||||||
|
err := this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleDNS, clusterId, 0, NSNodeTaskTypeDDosProtectionChanged)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更改
|
// NotifyUpdate 通知更改
|
||||||
func (this *NSClusterDAO) NotifyUpdate(tx *dbs.Tx, clusterId int64) error {
|
func (this *NSClusterDAO) NotifyUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleDNS, clusterId, 0, NSNodeTaskTypeConfigChanged)
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleDNS, clusterId, 0, NSNodeTaskTypeConfigChanged)
|
||||||
|
|||||||
@@ -4,31 +4,33 @@ import "github.com/iwind/TeaGo/dbs"
|
|||||||
|
|
||||||
// NSCluster 域名服务器集群
|
// NSCluster 域名服务器集群
|
||||||
type NSCluster struct {
|
type NSCluster struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
Name string `field:"name"` // 集群名
|
Name string `field:"name"` // 集群名
|
||||||
InstallDir string `field:"installDir"` // 安装目录
|
InstallDir string `field:"installDir"` // 安装目录
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
AccessLog dbs.JSON `field:"accessLog"` // 访问日志配置
|
AccessLog dbs.JSON `field:"accessLog"` // 访问日志配置
|
||||||
GrantId uint32 `field:"grantId"` // 授权ID
|
GrantId uint32 `field:"grantId"` // 授权ID
|
||||||
Recursion dbs.JSON `field:"recursion"` // 递归DNS设置
|
Recursion dbs.JSON `field:"recursion"` // 递归DNS设置
|
||||||
Tcp dbs.JSON `field:"tcp"` // TCP设置
|
Tcp dbs.JSON `field:"tcp"` // TCP设置
|
||||||
Tls dbs.JSON `field:"tls"` // TLS设置
|
Tls dbs.JSON `field:"tls"` // TLS设置
|
||||||
Udp dbs.JSON `field:"udp"` // UDP设置
|
Udp dbs.JSON `field:"udp"` // UDP设置
|
||||||
|
DdosProtection dbs.JSON `field:"ddosProtection"` // DDoS防护设置
|
||||||
}
|
}
|
||||||
|
|
||||||
type NSClusterOperator struct {
|
type NSClusterOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
Name interface{} // 集群名
|
Name any // 集群名
|
||||||
InstallDir interface{} // 安装目录
|
InstallDir any // 安装目录
|
||||||
State interface{} // 状态
|
State any // 状态
|
||||||
AccessLog interface{} // 访问日志配置
|
AccessLog any // 访问日志配置
|
||||||
GrantId interface{} // 授权ID
|
GrantId any // 授权ID
|
||||||
Recursion interface{} // 递归DNS设置
|
Recursion any // 递归DNS设置
|
||||||
Tcp interface{} // TCP设置
|
Tcp any // TCP设置
|
||||||
Tls interface{} // TLS设置
|
Tls any // TLS设置
|
||||||
Udp interface{} // UDP设置
|
Udp any // UDP设置
|
||||||
|
DdosProtection any // DDoS防护设置
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNSClusterOperator() *NSClusterOperator {
|
func NewNSClusterOperator() *NSClusterOperator {
|
||||||
|
|||||||
@@ -1 +1,29 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DecodeDDoSProtection 解析DDOS Protection设置
|
||||||
|
func (this *NSCluster) DecodeDDoSProtection() *ddosconfigs.ProtectionConfig {
|
||||||
|
if IsNull(this.DdosProtection) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = &ddosconfigs.ProtectionConfig{}
|
||||||
|
err := json.Unmarshal(this.DdosProtection, &result)
|
||||||
|
if err != nil {
|
||||||
|
// ignore err
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDDoSProtection 检查是否有DDOS设置
|
||||||
|
func (this *NSCluster) HasDDoSProtection() bool {
|
||||||
|
var config = this.DecodeDDoSProtection()
|
||||||
|
if config != nil {
|
||||||
|
return config.IsOn()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -9,12 +9,14 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -347,7 +349,7 @@ func (this *NSNodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstall
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNodeStatus 更改节点状态
|
// UpdateNodeStatus 更改节点状态
|
||||||
func (this NSNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, nodeStatus *nodeconfigs.NodeStatus) error {
|
func (this *NSNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, nodeStatus *nodeconfigs.NodeStatus) error {
|
||||||
if nodeStatus == nil {
|
if nodeStatus == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -484,6 +486,19 @@ func (this *NSNodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64) (*dnsconfigs.
|
|||||||
config.UDP = udpConfig
|
config.UDP = udpConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DDoS
|
||||||
|
config.DDoSProtection = cluster.DecodeDDoSProtection()
|
||||||
|
|
||||||
|
// DDoS Protection
|
||||||
|
var ddosProtection = node.DecodeDDoSProtection()
|
||||||
|
if ddosProtection != nil {
|
||||||
|
if config.DDoSProtection == nil {
|
||||||
|
config.DDoSProtection = ddosProtection
|
||||||
|
} else {
|
||||||
|
config.DDoSProtection.Merge(ddosProtection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,6 +531,7 @@ func (this *NSNodeDAO) UpdateNodeActive(tx *dbs.Tx, nodeId int64, isActive bool)
|
|||||||
Pk(nodeId).
|
Pk(nodeId).
|
||||||
Set("isActive", isActive).
|
Set("isActive", isActive).
|
||||||
Set("statusIsNotified", false).
|
Set("statusIsNotified", false).
|
||||||
|
Set("inactiveNotifiedAt", 0).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -562,9 +578,18 @@ func (this *NSNodeDAO) UpdateNodeStatusIsNotified(tx *dbs.Tx, nodeId int64) erro
|
|||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(nodeId).
|
Pk(nodeId).
|
||||||
Set("statusIsNotified", true).
|
Set("statusIsNotified", true).
|
||||||
|
Set("inactiveNotifiedAt", time.Now().Unix()).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindNodeInactiveNotifiedAt 读取上次的节点离线通知时间
|
||||||
|
func (this *NSNodeDAO) FindNodeInactiveNotifiedAt(tx *dbs.Tx, nodeId int64) (int64, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(nodeId).
|
||||||
|
Result("inactiveNotifiedAt").
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
// FindAllNodeIdsMatch 匹配节点并返回节点ID
|
// FindAllNodeIdsMatch 匹配节点并返回节点ID
|
||||||
func (this *NSNodeDAO) FindAllNodeIdsMatch(tx *dbs.Tx, clusterId int64, includeSecondaryNodes bool, isOn configutils.BoolState) (result []int64, err error) {
|
func (this *NSNodeDAO) FindAllNodeIdsMatch(tx *dbs.Tx, clusterId int64, includeSecondaryNodes bool, isOn configutils.BoolState) (result []int64, err error) {
|
||||||
query := this.Query(tx)
|
query := this.Query(tx)
|
||||||
@@ -629,6 +654,53 @@ func (this *NSNodeDAO) FindEnabledNodeIdsWithClusterId(tx *dbs.Tx, clusterId int
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindNodeDDoSProtection 获取节点的DDOS设置
|
||||||
|
func (this *NSNodeDAO) FindNodeDDoSProtection(tx *dbs.Tx, nodeId int64) (*ddosconfigs.ProtectionConfig, error) {
|
||||||
|
one, err := this.Query(tx).
|
||||||
|
Result("ddosProtection").
|
||||||
|
Pk(nodeId).
|
||||||
|
Find()
|
||||||
|
if one == nil || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return one.(*NSNode).DecodeDDoSProtection(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNodeDDoSProtection 设置集群的DDOS设置
|
||||||
|
func (this *NSNodeDAO) UpdateNodeDDoSProtection(tx *dbs.Tx, nodeId int64, ddosProtection *ddosconfigs.ProtectionConfig) error {
|
||||||
|
if nodeId <= 0 {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
var op = NewNSNodeOperator()
|
||||||
|
op.Id = nodeId
|
||||||
|
|
||||||
|
if ddosProtection == nil {
|
||||||
|
op.DdosProtection = "{}"
|
||||||
|
} else {
|
||||||
|
ddosProtectionJSON, err := json.Marshal(ddosProtection)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.DdosProtection = ddosProtectionJSON
|
||||||
|
}
|
||||||
|
|
||||||
|
err := this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterId, err := this.FindNodeClusterId(tx, nodeId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if clusterId > 0 {
|
||||||
|
return SharedNodeTaskDAO.CreateNodeTask(tx, nodeconfigs.NodeRoleDNS, clusterId, nodeId, 0, NSNodeTaskTypeDDosProtectionChanged, 0)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *NSNodeDAO) NotifyUpdate(tx *dbs.Tx, nodeId int64) error {
|
func (this *NSNodeDAO) NotifyUpdate(tx *dbs.Tx, nodeId int64) error {
|
||||||
// TODO 先什么都不做
|
// TODO 先什么都不做
|
||||||
|
|||||||
@@ -4,41 +4,45 @@ import "github.com/iwind/TeaGo/dbs"
|
|||||||
|
|
||||||
// NSNode 域名服务器节点
|
// NSNode 域名服务器节点
|
||||||
type NSNode struct {
|
type NSNode struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||||
Name string `field:"name"` // 节点名称
|
Name string `field:"name"` // 节点名称
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
Status dbs.JSON `field:"status"` // 运行状态
|
Status dbs.JSON `field:"status"` // 运行状态
|
||||||
UniqueId string `field:"uniqueId"` // 节点ID
|
UniqueId string `field:"uniqueId"` // 节点ID
|
||||||
Secret string `field:"secret"` // 密钥
|
Secret string `field:"secret"` // 密钥
|
||||||
IsUp bool `field:"isUp"` // 是否运行
|
IsUp bool `field:"isUp"` // 是否运行
|
||||||
IsInstalled bool `field:"isInstalled"` // 是否已安装
|
IsInstalled bool `field:"isInstalled"` // 是否已安装
|
||||||
InstallStatus dbs.JSON `field:"installStatus"` // 安装状态
|
InstallStatus dbs.JSON `field:"installStatus"` // 安装状态
|
||||||
InstallDir string `field:"installDir"` // 安装目录
|
InstallDir string `field:"installDir"` // 安装目录
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
IsActive bool `field:"isActive"` // 是否活跃
|
IsActive bool `field:"isActive"` // 是否活跃
|
||||||
StatusIsNotified uint8 `field:"statusIsNotified"` // 活跃状态已经通知
|
StatusIsNotified uint8 `field:"statusIsNotified"` // 活跃状态已经通知
|
||||||
ConnectedAPINodes dbs.JSON `field:"connectedAPINodes"` // 当前连接的API节点
|
InactiveNotifiedAt uint64 `field:"inactiveNotifiedAt"` // 离线通知时间
|
||||||
|
ConnectedAPINodes dbs.JSON `field:"connectedAPINodes"` // 当前连接的API节点
|
||||||
|
DdosProtection dbs.JSON `field:"ddosProtection"` // DDoS防护设置
|
||||||
}
|
}
|
||||||
|
|
||||||
type NSNodeOperator struct {
|
type NSNodeOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
ClusterId interface{} // 集群ID
|
ClusterId any // 集群ID
|
||||||
Name interface{} // 节点名称
|
Name any // 节点名称
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
Status interface{} // 运行状态
|
Status any // 运行状态
|
||||||
UniqueId interface{} // 节点ID
|
UniqueId any // 节点ID
|
||||||
Secret interface{} // 密钥
|
Secret any // 密钥
|
||||||
IsUp interface{} // 是否运行
|
IsUp any // 是否运行
|
||||||
IsInstalled interface{} // 是否已安装
|
IsInstalled any // 是否已安装
|
||||||
InstallStatus interface{} // 安装状态
|
InstallStatus any // 安装状态
|
||||||
InstallDir interface{} // 安装目录
|
InstallDir any // 安装目录
|
||||||
State interface{} // 状态
|
State any // 状态
|
||||||
IsActive interface{} // 是否活跃
|
IsActive any // 是否活跃
|
||||||
StatusIsNotified interface{} // 活跃状态已经通知
|
StatusIsNotified any // 活跃状态已经通知
|
||||||
ConnectedAPINodes interface{} // 当前连接的API节点
|
InactiveNotifiedAt any // 离线通知时间
|
||||||
|
ConnectedAPINodes any // 当前连接的API节点
|
||||||
|
DdosProtection any // DDoS防护设置
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNSNodeOperator() *NSNodeOperator {
|
func NewNSNodeOperator() *NSNodeOperator {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -39,3 +40,40 @@ func (this *NSNode) DecodeStatus() (*nodeconfigs.NodeStatus, error) {
|
|||||||
}
|
}
|
||||||
return status, nil
|
return status, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeDDoSProtection 解析DDoS Protection设置
|
||||||
|
func (this *NSNode) DecodeDDoSProtection() *ddosconfigs.ProtectionConfig {
|
||||||
|
if IsNull(this.DdosProtection) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = &ddosconfigs.ProtectionConfig{}
|
||||||
|
err := json.Unmarshal(this.DdosProtection, &result)
|
||||||
|
if err != nil {
|
||||||
|
// ignore err
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDDoSProtection 检查是否有DDOS设置
|
||||||
|
func (this *NSNode) HasDDoSProtection() bool {
|
||||||
|
var config = this.DecodeDDoSProtection()
|
||||||
|
if config != nil {
|
||||||
|
return !config.IsPriorEmpty()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeConnectedAPINodes 解析连接的API节点列表
|
||||||
|
func (this *NSNode) DecodeConnectedAPINodes() []int64 {
|
||||||
|
if IsNull(this.ConnectedAPINodes) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = []int64{}
|
||||||
|
err := json.Unmarshal(this.ConnectedAPINodes, &result)
|
||||||
|
if err != nil {
|
||||||
|
// ignore err
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -162,3 +162,19 @@ func (this *RegionTownDAO) FindSimilarTowns(towns []*RegionTown, townName string
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateTown 创建区县
|
||||||
|
func (this *RegionTownDAO) CreateTown(tx *dbs.Tx, cityId int64, townName string) (int64, error) {
|
||||||
|
var op = NewRegionTownOperator()
|
||||||
|
op.CityId = cityId
|
||||||
|
op.Name = townName
|
||||||
|
|
||||||
|
codes, err := json.Marshal([]string{townName})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.Codes = codes
|
||||||
|
|
||||||
|
op.State = RegionTownStateEnabled
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -12,6 +14,7 @@ import (
|
|||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
"math"
|
"math"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -89,6 +92,59 @@ func (this *ServerBandwidthStatDAO) FindMinutelyPeekBandwidthBytes(tx *dbs.Tx, s
|
|||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindHourlyBandwidthStats 按小时获取带宽峰值
|
||||||
|
func (this *ServerBandwidthStatDAO) FindHourlyBandwidthStats(tx *dbs.Tx, serverId int64, hours int32) (result []*pb.FindHourlyServerBandwidthStatsResponse_Stat, err error) {
|
||||||
|
if hours <= 0 {
|
||||||
|
hours = 24
|
||||||
|
}
|
||||||
|
|
||||||
|
var timestamp = time.Now().Unix() - int64(hours)*3600
|
||||||
|
|
||||||
|
ones, _, err := this.Query(tx).
|
||||||
|
Table(this.partialTable(serverId)).
|
||||||
|
Result("MAX(bytes) AS bytes", "CONCAT(day, '.', SUBSTRING(timeAt, 1, 2)) AS fullTime").
|
||||||
|
Attr("serverId", serverId).
|
||||||
|
Gte("CONCAT(day, '.', SUBSTRING(timeAt, 1, 2))", timeutil.FormatTime("Ymd.H", timestamp)).
|
||||||
|
Group("fullTime").
|
||||||
|
FindOnes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var m = map[string]*pb.FindHourlyServerBandwidthStatsResponse_Stat{}
|
||||||
|
for _, one := range ones {
|
||||||
|
var fullTime = one.GetString("fullTime")
|
||||||
|
var timePieces = strings.Split(fullTime, ".")
|
||||||
|
var day = timePieces[0]
|
||||||
|
var hour = timePieces[1]
|
||||||
|
|
||||||
|
m[day+hour] = &pb.FindHourlyServerBandwidthStatsResponse_Stat{
|
||||||
|
Bytes: one.GetInt64("bytes"),
|
||||||
|
Day: day,
|
||||||
|
Hour: types.Int32(hour),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fullHours, err := utils.RangeHours(timeutil.FormatTime("YmdH", timestamp), timeutil.Format("YmdH"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, fullHour := range fullHours {
|
||||||
|
stat, ok := m[fullHour]
|
||||||
|
if ok {
|
||||||
|
result = append(result, stat)
|
||||||
|
} else {
|
||||||
|
result = append(result, &pb.FindHourlyServerBandwidthStatsResponse_Stat{
|
||||||
|
Bytes: 0,
|
||||||
|
Day: fullHour[:8],
|
||||||
|
Hour: types.Int32(fullHour[8:]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FindDailyPeekBandwidthBytes 获取某天的带宽峰值
|
// FindDailyPeekBandwidthBytes 获取某天的带宽峰值
|
||||||
// day YYYYMMDD
|
// day YYYYMMDD
|
||||||
func (this *ServerBandwidthStatDAO) FindDailyPeekBandwidthBytes(tx *dbs.Tx, serverId int64, day string) (int64, error) {
|
func (this *ServerBandwidthStatDAO) FindDailyPeekBandwidthBytes(tx *dbs.Tx, serverId int64, day string) (int64, error) {
|
||||||
@@ -99,6 +155,54 @@ func (this *ServerBandwidthStatDAO) FindDailyPeekBandwidthBytes(tx *dbs.Tx, serv
|
|||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindDailyBandwidthStats 按天获取带宽峰值
|
||||||
|
func (this *ServerBandwidthStatDAO) FindDailyBandwidthStats(tx *dbs.Tx, serverId int64, days int32) (result []*pb.FindDailyServerBandwidthStatsResponse_Stat, err error) {
|
||||||
|
if days <= 0 {
|
||||||
|
days = 14
|
||||||
|
}
|
||||||
|
|
||||||
|
var timestamp = time.Now().Unix() - int64(days)*86400
|
||||||
|
|
||||||
|
ones, _, err := this.Query(tx).
|
||||||
|
Table(this.partialTable(serverId)).
|
||||||
|
Result("MAX(bytes) AS bytes", "day").
|
||||||
|
Attr("serverId", serverId).
|
||||||
|
Gte("day", timeutil.FormatTime("Ymd", timestamp)).
|
||||||
|
Group("day").
|
||||||
|
FindOnes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var m = map[string]*pb.FindDailyServerBandwidthStatsResponse_Stat{}
|
||||||
|
for _, one := range ones {
|
||||||
|
var day = one.GetString("day")
|
||||||
|
|
||||||
|
m[day] = &pb.FindDailyServerBandwidthStatsResponse_Stat{
|
||||||
|
Bytes: one.GetInt64("bytes"),
|
||||||
|
Day: day,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allDays, err := utils.RangeDays(timeutil.FormatTime("Ymd", timestamp), timeutil.Format("Ymd"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, day := range allDays {
|
||||||
|
stat, ok := m[day]
|
||||||
|
if ok {
|
||||||
|
result = append(result, stat)
|
||||||
|
} else {
|
||||||
|
result = append(result, &pb.FindDailyServerBandwidthStatsResponse_Stat{
|
||||||
|
Bytes: 0,
|
||||||
|
Day: day,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FindMonthlyPeekBandwidthBytes 获取某月的带宽峰值
|
// FindMonthlyPeekBandwidthBytes 获取某月的带宽峰值
|
||||||
// month YYYYMM
|
// month YYYYMM
|
||||||
func (this *ServerBandwidthStatDAO) FindMonthlyPeekBandwidthBytes(tx *dbs.Tx, serverId int64, month string) (int64, error) {
|
func (this *ServerBandwidthStatDAO) FindMonthlyPeekBandwidthBytes(tx *dbs.Tx, serverId int64, month string) (int64, error) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -77,3 +78,24 @@ func TestServerBandwidthStatDAO_Clean(t *testing.T) {
|
|||||||
}
|
}
|
||||||
t.Log("ok", time.Since(before).Seconds()*1000, "ms")
|
t.Log("ok", time.Since(before).Seconds()*1000, "ms")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServerBandwidthStatDAO_FindHourlyBandwidthStats(t *testing.T) {
|
||||||
|
var dao = models.NewServerBandwidthStatDAO()
|
||||||
|
var tx *dbs.Tx
|
||||||
|
stats, err := dao.FindHourlyBandwidthStats(tx, 23, 24)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
logs.PrintAsJSON(stats, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func TestServerBandwidthStatDAO_FindDailyBandwidthStats(t *testing.T) {
|
||||||
|
var dao = models.NewServerBandwidthStatDAO()
|
||||||
|
var tx *dbs.Tx
|
||||||
|
stats, err := dao.FindDailyBandwidthStats(tx, 23, 14)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
logs.PrintAsJSON(stats, t)
|
||||||
|
}
|
||||||
@@ -759,7 +759,8 @@ func (this *ServerDAO) CountAllEnabledServers(tx *dbs.Tx) (int64, error) {
|
|||||||
|
|
||||||
// CountAllEnabledServersMatch 计算所有可用服务数量
|
// CountAllEnabledServersMatch 计算所有可用服务数量
|
||||||
// 参数:
|
// 参数:
|
||||||
// groupId 分组ID,如果为-1,则搜索没有分组的服务
|
//
|
||||||
|
// groupId 分组ID,如果为-1,则搜索没有分组的服务
|
||||||
func (this *ServerDAO) CountAllEnabledServersMatch(tx *dbs.Tx, groupId int64, keyword string, userId int64, clusterId int64, auditingFlag configutils.BoolState, protocolFamilies []string) (int64, error) {
|
func (this *ServerDAO) CountAllEnabledServersMatch(tx *dbs.Tx, groupId int64, keyword string, userId int64, clusterId int64, auditingFlag configutils.BoolState, protocolFamilies []string) (int64, error) {
|
||||||
query := this.Query(tx).
|
query := this.Query(tx).
|
||||||
State(ServerStateEnabled)
|
State(ServerStateEnabled)
|
||||||
@@ -810,7 +811,8 @@ func (this *ServerDAO) CountAllEnabledServersMatch(tx *dbs.Tx, groupId int64, ke
|
|||||||
|
|
||||||
// ListEnabledServersMatch 列出单页的服务
|
// ListEnabledServersMatch 列出单页的服务
|
||||||
// 参数:
|
// 参数:
|
||||||
// groupId 分组ID,如果为-1,则搜索没有分组的服务
|
//
|
||||||
|
// groupId 分组ID,如果为-1,则搜索没有分组的服务
|
||||||
func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size int64, groupId int64, keyword string, userId int64, clusterId int64, auditingFlag int32, protocolFamilies []string, order string) (result []*Server, err error) {
|
func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size int64, groupId int64, keyword string, userId int64, clusterId int64, auditingFlag int32, protocolFamilies []string, order string) (result []*Server, err error) {
|
||||||
query := this.Query(tx).
|
query := this.Query(tx).
|
||||||
State(ServerStateEnabled).
|
State(ServerStateEnabled).
|
||||||
@@ -860,49 +862,32 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 排序
|
// 排序
|
||||||
var day = timeutil.Format("Ymd")
|
var timestamp = time.Now().Unix() / 300 * 300
|
||||||
var minute = timeutil.FormatTime("His", time.Now().Unix()/300*300-300)
|
var currentTime = timeutil.FormatTime("YmdHi", timestamp)
|
||||||
var selfTable = this.Table
|
var prevTime = timeutil.FormatTime("YmdHi", timestamp-300)
|
||||||
var statTable = SharedServerDailyStatDAO.Table
|
|
||||||
var hasOnlyIds = false
|
|
||||||
switch order {
|
switch order {
|
||||||
case "trafficOutAsc":
|
case "trafficOutAsc":
|
||||||
query.Result("id")
|
query.Asc("IF(IF(bandwidthTime=:currentTime, bandwidthBytes, 0) > 0, IF(bandwidthTime=:currentTime, bandwidthBytes, 0), IF(bandwidthTime=:prevTime, bandwidthBytes, 0))")
|
||||||
query.Join(SharedServerDailyStatDAO, dbs.QueryJoinLeft, selfTable+".id="+statTable+".serverId AND "+statTable+".day=:day AND "+statTable+".timeFrom=:minute")
|
query.Param("currentTime", currentTime)
|
||||||
query.Param("day", day)
|
query.Param("prevTime", prevTime)
|
||||||
query.Param("minute", minute)
|
query.DescPk()
|
||||||
query.Group(selfTable + ".id")
|
|
||||||
query.Asc("SUM(" + statTable + ".bytes)").
|
|
||||||
DescPk()
|
|
||||||
hasOnlyIds = true
|
|
||||||
case "trafficOutDesc":
|
case "trafficOutDesc":
|
||||||
query.Result("id")
|
query.Desc("IF(IF(bandwidthTime=:currentTime, bandwidthBytes, 0) > 0, IF(bandwidthTime=:currentTime, bandwidthBytes, 0), IF(bandwidthTime=:prevTime, bandwidthBytes, 0))")
|
||||||
query.Join(SharedServerDailyStatDAO, dbs.QueryJoinLeft, selfTable+".id="+statTable+".serverId AND "+statTable+".day=:day AND "+statTable+".timeFrom=:minute")
|
query.Param("currentTime", currentTime)
|
||||||
query.Param("day", day)
|
query.Param("prevTime", prevTime)
|
||||||
query.Param("minute", minute)
|
query.DescPk()
|
||||||
query.Group(selfTable + ".id")
|
|
||||||
query.Desc("SUM(" + statTable + ".bytes)").
|
|
||||||
DescPk()
|
|
||||||
hasOnlyIds = true
|
|
||||||
default:
|
default:
|
||||||
query.DescPk()
|
query.DescPk()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = query.FindAll()
|
_, err = query.FindAll()
|
||||||
|
|
||||||
if hasOnlyIds {
|
// 修正带宽统计数据
|
||||||
var newResult = []*Server{}
|
for _, server := range result {
|
||||||
for _, one := range result {
|
if len(server.BandwidthTime) > 0 && server.BandwidthBytes > 0 && server.BandwidthTime < prevTime {
|
||||||
server, err := this.Find(tx, one.Id)
|
server.BandwidthBytes = 0
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if server == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
newResult = append(newResult, server.(*Server))
|
|
||||||
}
|
}
|
||||||
result = newResult
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -1629,6 +1614,33 @@ func (this *ServerDAO) GenerateServerDNSName(tx *dbs.Tx, serverId int64) (string
|
|||||||
return dnsName, nil
|
return dnsName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateServerDNSName 设置CNAME
|
||||||
|
func (this *ServerDAO) UpdateServerDNSName(tx *dbs.Tx, serverId int64, dnsName string) error {
|
||||||
|
if serverId <= 0 || len(dnsName) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
dnsName = strings.ToLower(dnsName)
|
||||||
|
err := this.Query(tx).
|
||||||
|
Pk(serverId).
|
||||||
|
Set("dnsName", dnsName).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyDNSUpdate(tx, serverId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindServerIdWithDNSName 根据CNAME查询服务ID
|
||||||
|
func (this *ServerDAO) FindServerIdWithDNSName(tx *dbs.Tx, clusterId int64, dnsName string) (int64, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
ResultPk().
|
||||||
|
State(ServerStateEnabled).
|
||||||
|
Attr("clusterId", clusterId).
|
||||||
|
Attr("dnsName", dnsName).
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
// FindServerClusterId 查询当前服务的集群ID
|
// FindServerClusterId 查询当前服务的集群ID
|
||||||
func (this *ServerDAO) FindServerClusterId(tx *dbs.Tx, serverId int64) (int64, error) {
|
func (this *ServerDAO) FindServerClusterId(tx *dbs.Tx, serverId int64) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
@@ -2549,6 +2561,22 @@ func (this *ServerDAO) FindUserServerClusterIds(tx *dbs.Tx, userId int64) ([]int
|
|||||||
return clusterIds, nil
|
return clusterIds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateServerBandwidth 更新服务带宽
|
||||||
|
// fullTime YYYYMMDDHHII
|
||||||
|
func (this *ServerDAO) UpdateServerBandwidth(tx *dbs.Tx, serverId int64, fullTime string, bandwidthBytes int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if bandwidthBytes < 0 {
|
||||||
|
bandwidthBytes = 0
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(serverId).
|
||||||
|
Set("bandwidthTime", fullTime).
|
||||||
|
Set("bandwidthBytes", bandwidthBytes).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 同步服务所在的集群
|
// NotifyUpdate 同步服务所在的集群
|
||||||
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
||||||
// 创建任务
|
// 创建任务
|
||||||
|
|||||||
@@ -48,53 +48,57 @@ type Server struct {
|
|||||||
UserPlanId uint32 `field:"userPlanId"` // 所属套餐ID
|
UserPlanId uint32 `field:"userPlanId"` // 所属套餐ID
|
||||||
LastUserPlanId uint32 `field:"lastUserPlanId"` // 上一次使用的套餐
|
LastUserPlanId uint32 `field:"lastUserPlanId"` // 上一次使用的套餐
|
||||||
Uam dbs.JSON `field:"uam"` // UAM设置
|
Uam dbs.JSON `field:"uam"` // UAM设置
|
||||||
|
BandwidthTime string `field:"bandwidthTime"` // 带宽更新时间,YYYYMMDDHHII
|
||||||
|
BandwidthBytes uint64 `field:"bandwidthBytes"` // 最近带宽峰值
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerOperator struct {
|
type ServerOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
Type interface{} // 服务类型
|
Type any // 服务类型
|
||||||
Name interface{} // 名称
|
Name any // 名称
|
||||||
Description interface{} // 描述
|
Description any // 描述
|
||||||
PlainServerNames interface{} // 扁平化域名列表
|
PlainServerNames any // 扁平化域名列表
|
||||||
ServerNames interface{} // 域名列表
|
ServerNames any // 域名列表
|
||||||
AuditingAt interface{} // 审核提交时间
|
AuditingAt any // 审核提交时间
|
||||||
AuditingServerNames interface{} // 审核中的域名
|
AuditingServerNames any // 审核中的域名
|
||||||
IsAuditing interface{} // 是否正在审核
|
IsAuditing any // 是否正在审核
|
||||||
AuditingResult interface{} // 审核结果
|
AuditingResult any // 审核结果
|
||||||
Http interface{} // HTTP配置
|
Http any // HTTP配置
|
||||||
Https interface{} // HTTPS配置
|
Https any // HTTPS配置
|
||||||
Tcp interface{} // TCP配置
|
Tcp any // TCP配置
|
||||||
Tls interface{} // TLS配置
|
Tls any // TLS配置
|
||||||
Unix interface{} // Unix配置
|
Unix any // Unix配置
|
||||||
Udp interface{} // UDP配置
|
Udp any // UDP配置
|
||||||
WebId interface{} // WEB配置
|
WebId any // WEB配置
|
||||||
ReverseProxy interface{} // 反向代理配置
|
ReverseProxy any // 反向代理配置
|
||||||
GroupIds interface{} // 分组ID列表
|
GroupIds any // 分组ID列表
|
||||||
Config interface{} // 服务配置,自动生成
|
Config any // 服务配置,自动生成
|
||||||
ConfigMd5 interface{} // Md5
|
ConfigMd5 any // Md5
|
||||||
ClusterId interface{} // 集群ID
|
ClusterId any // 集群ID
|
||||||
IncludeNodes interface{} // 部署条件
|
IncludeNodes any // 部署条件
|
||||||
ExcludeNodes interface{} // 节点排除条件
|
ExcludeNodes any // 节点排除条件
|
||||||
Version interface{} // 版本号
|
Version any // 版本号
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt any // 创建时间
|
||||||
State interface{} // 状态
|
State any // 状态
|
||||||
DnsName interface{} // DNS名称
|
DnsName any // DNS名称
|
||||||
TcpPorts interface{} // 所包含TCP端口
|
TcpPorts any // 所包含TCP端口
|
||||||
UdpPorts interface{} // 所包含UDP端口
|
UdpPorts any // 所包含UDP端口
|
||||||
SupportCNAME interface{} // 允许CNAME不在域名名单
|
SupportCNAME any // 允许CNAME不在域名名单
|
||||||
TrafficLimit interface{} // 流量限制
|
TrafficLimit any // 流量限制
|
||||||
TrafficDay interface{} // YYYYMMDD
|
TrafficDay any // YYYYMMDD
|
||||||
TrafficMonth interface{} // YYYYMM
|
TrafficMonth any // YYYYMM
|
||||||
TotalDailyTraffic interface{} // 日流量
|
TotalDailyTraffic any // 日流量
|
||||||
TotalMonthlyTraffic interface{} // 月流量
|
TotalMonthlyTraffic any // 月流量
|
||||||
TrafficLimitStatus interface{} // 流量限制状态
|
TrafficLimitStatus any // 流量限制状态
|
||||||
TotalTraffic interface{} // 总流量
|
TotalTraffic any // 总流量
|
||||||
UserPlanId interface{} // 所属套餐ID
|
UserPlanId any // 所属套餐ID
|
||||||
LastUserPlanId interface{} // 上一次使用的套餐
|
LastUserPlanId any // 上一次使用的套餐
|
||||||
Uam interface{} // UAM设置
|
Uam any // UAM设置
|
||||||
|
BandwidthTime any // 带宽更新时间,YYYYMMDDHHII
|
||||||
|
BandwidthBytes any // 最近带宽峰值
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServerOperator() *ServerOperator {
|
func NewServerOperator() *ServerOperator {
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ func (this *SSLCertDAO) FindAllExpiringCerts(tx *dbs.Tx, days int) (result []*SS
|
|||||||
days = 0
|
days = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
deltaSeconds := int64(days * 86400)
|
var deltaSeconds = int64(days * 86400)
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(SSLCertStateEnabled).
|
State(SSLCertStateEnabled).
|
||||||
Where("FROM_UNIXTIME(timeEndAt, '%Y-%m-%d')=:day AND FROM_UNIXTIME(notifiedAt, '%Y-%m-%d')!=:today").
|
Where("FROM_UNIXTIME(timeEndAt, '%Y-%m-%d')=:day AND FROM_UNIXTIME(notifiedAt, '%Y-%m-%d')!=:today").
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
@@ -352,7 +353,7 @@ func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error)
|
|||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUserFeatures 更新用户Features
|
// UpdateUserFeatures 更新单个用户Features
|
||||||
func (this *UserDAO) UpdateUserFeatures(tx *dbs.Tx, userId int64, featuresJSON []byte) error {
|
func (this *UserDAO) UpdateUserFeatures(tx *dbs.Tx, userId int64, featuresJSON []byte) error {
|
||||||
if userId <= 0 {
|
if userId <= 0 {
|
||||||
return errors.New("invalid userId")
|
return errors.New("invalid userId")
|
||||||
@@ -370,6 +371,74 @@ func (this *UserDAO) UpdateUserFeatures(tx *dbs.Tx, userId int64, featuresJSON [
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateUsersFeatures 更新所有用户的Features
|
||||||
|
func (this *UserDAO) UpdateUsersFeatures(tx *dbs.Tx, featureCodes []string, overwrite bool) error {
|
||||||
|
if featureCodes == nil {
|
||||||
|
featureCodes = []string{}
|
||||||
|
}
|
||||||
|
if overwrite {
|
||||||
|
featureCodesJSON, err := json.Marshal(featureCodes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = this.Query(tx).
|
||||||
|
State(UserStateEnabled).
|
||||||
|
Set("features", featureCodesJSON).
|
||||||
|
UpdateQuickly()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastId int64
|
||||||
|
const size = 1000
|
||||||
|
for {
|
||||||
|
ones, _, err := this.Query(tx).
|
||||||
|
Result("id", "features").
|
||||||
|
State(UserStateEnabled).
|
||||||
|
Gt("id", lastId).
|
||||||
|
Limit(size).
|
||||||
|
AscPk().
|
||||||
|
FindOnes()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, one := range ones {
|
||||||
|
var userId = one.GetInt64("id")
|
||||||
|
var userFeaturesJSON = one.GetBytes("features")
|
||||||
|
var userFeatures = []string{}
|
||||||
|
if len(userFeaturesJSON) > 0 {
|
||||||
|
err = json.Unmarshal(userFeaturesJSON, &userFeatures)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, featureCode := range featureCodes {
|
||||||
|
if !lists.ContainsString(userFeatures, featureCode) {
|
||||||
|
userFeatures = append(userFeatures, featureCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userFeaturesJSON, err = json.Marshal(userFeatures)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(userId).
|
||||||
|
Set("features", userFeaturesJSON).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ones) < size {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
lastId += size
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// FindUserFeatures 查找用户Features
|
// FindUserFeatures 查找用户Features
|
||||||
func (this *UserDAO) FindUserFeatures(tx *dbs.Tx, userId int64) ([]*userconfigs.UserFeature, error) {
|
func (this *UserDAO) FindUserFeatures(tx *dbs.Tx, userId int64) ([]*userconfigs.UserFeature, error) {
|
||||||
featuresJSON, err := this.Query(tx).
|
featuresJSON, err := this.Query(tx).
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestUserDAO_UpdateUserFeatures(t *testing.T) {
|
||||||
|
var dao = NewUserDAO()
|
||||||
|
var tx *dbs.Tx
|
||||||
|
err := dao.UpdateUsersFeatures(tx, []string{
|
||||||
|
userconfigs.UserFeatureCodeFinance,
|
||||||
|
userconfigs.UserFeatureCodeServerACME,
|
||||||
|
}, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ secret: "${nodeSecret}"`)
|
|||||||
_, stderr, err = this.client.Exec(dir + "/edge-node/bin/edge-node test")
|
_, stderr, err = this.client.Exec(dir + "/edge-node/bin/edge-node test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
installStatus.ErrorCode = "TEST_FAILED"
|
installStatus.ErrorCode = "TEST_FAILED"
|
||||||
return errors.New("test edge node failed: " + err.Error())
|
return errors.New("test edge node failed: " + err.Error() + ", stderr: " + stderr)
|
||||||
}
|
}
|
||||||
if len(stderr) > 0 {
|
if len(stderr) > 0 {
|
||||||
if regexp.MustCompile(`(?i)rpc`).MatchString(stderr) {
|
if regexp.MustCompile(`(?i)rpc`).MatchString(stderr) {
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ secret: "${nodeSecret}"`)
|
|||||||
_, stderr, err = this.client.Exec(dir + "/edge-dns/bin/edge-dns test")
|
_, stderr, err = this.client.Exec(dir + "/edge-dns/bin/edge-dns test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
installStatus.ErrorCode = "TEST_FAILED"
|
installStatus.ErrorCode = "TEST_FAILED"
|
||||||
return errors.New("test edge node failed: " + err.Error())
|
return errors.New("test edge node failed: " + err.Error() + ", stderr: " + stderr)
|
||||||
}
|
}
|
||||||
if len(stderr) > 0 {
|
if len(stderr) > 0 {
|
||||||
if regexp.MustCompile(`(?i)rpc`).MatchString(stderr) {
|
if regexp.MustCompile(`(?i)rpc`).MatchString(stderr) {
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
// 源码改自:https://github.com/lionsoul2014/ip2region/blob/master/binding/golang/ip2region/ip2Region.go
|
|
||||||
|
|
||||||
package iplibrary
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
IndexBlockLength = 12
|
|
||||||
)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
type IP2Region struct {
|
|
||||||
headerSip []int64
|
|
||||||
headerPtr []int64
|
|
||||||
headerLen int64
|
|
||||||
|
|
||||||
// super block index info
|
|
||||||
firstIndexPtr int64
|
|
||||||
lastIndexPtr int64
|
|
||||||
totalBlocks int64
|
|
||||||
|
|
||||||
dbData []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type IpInfo struct {
|
|
||||||
CityId int64
|
|
||||||
Country string
|
|
||||||
Region string
|
|
||||||
Province string
|
|
||||||
City string
|
|
||||||
ISP string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ip IpInfo) String() string {
|
|
||||||
return strconv.FormatInt(ip.CityId, 10) + "|" + ip.Country + "|" + ip.Region + "|" + ip.Province + "|" + ip.City + "|" + ip.ISP
|
|
||||||
}
|
|
||||||
|
|
||||||
func getIpInfo(cityId int64, line []byte) *IpInfo {
|
|
||||||
lineSlice := strings.Split(string(line), "|")
|
|
||||||
ipInfo := &IpInfo{}
|
|
||||||
length := len(lineSlice)
|
|
||||||
ipInfo.CityId = cityId
|
|
||||||
if length < 5 {
|
|
||||||
for i := 0; i <= 5-length; i++ {
|
|
||||||
lineSlice = append(lineSlice, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ipInfo.Country = lineSlice[0]
|
|
||||||
ipInfo.Region = lineSlice[1]
|
|
||||||
ipInfo.Province = lineSlice[2]
|
|
||||||
ipInfo.City = lineSlice[3]
|
|
||||||
ipInfo.ISP = lineSlice[4]
|
|
||||||
return ipInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIP2Region(path string) (*IP2Region, error) {
|
|
||||||
var region = &IP2Region{}
|
|
||||||
region.dbData, err = os.ReadFile(path)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
region.firstIndexPtr = region.ipLongAtOffset(0)
|
|
||||||
region.lastIndexPtr = region.ipLongAtOffset(4)
|
|
||||||
region.totalBlocks = (region.lastIndexPtr-region.firstIndexPtr)/IndexBlockLength + 1
|
|
||||||
return region, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *IP2Region) MemorySearch(ipStr string) (ipInfo *IpInfo, err error) {
|
|
||||||
ip, err := ip2long(ipStr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
h := this.totalBlocks
|
|
||||||
var dataPtr, l int64
|
|
||||||
for l <= h {
|
|
||||||
m := (l + h) >> 1
|
|
||||||
p := this.firstIndexPtr + m*IndexBlockLength
|
|
||||||
sip := this.ipLongAtOffset(p)
|
|
||||||
if ip < sip {
|
|
||||||
h = m - 1
|
|
||||||
} else {
|
|
||||||
eip := this.ipLongAtOffset(p + 4)
|
|
||||||
if ip > eip {
|
|
||||||
l = m + 1
|
|
||||||
} else {
|
|
||||||
dataPtr = this.ipLongAtOffset(p + 8)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if dataPtr == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dataLen := (dataPtr >> 24) & 0xFF
|
|
||||||
dataPtr = dataPtr & 0x00FFFFFF
|
|
||||||
return getIpInfo(this.ipLongAtOffset(dataPtr), this.dbData[(dataPtr)+4:dataPtr+dataLen]), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *IP2Region) ipLongAtOffset(offset int64) int64 {
|
|
||||||
return int64(this.dbData[offset]) |
|
|
||||||
int64(this.dbData[offset+1])<<8 |
|
|
||||||
int64(this.dbData[offset+2])<<16 |
|
|
||||||
int64(this.dbData[offset+3])<<24
|
|
||||||
}
|
|
||||||
|
|
||||||
func ip2long(IpStr string) (int64, error) {
|
|
||||||
bits := strings.Split(IpStr, ".")
|
|
||||||
if len(bits) != 4 {
|
|
||||||
return 0, errors.New("ip format error")
|
|
||||||
}
|
|
||||||
|
|
||||||
var sum int64
|
|
||||||
for i, n := range bits {
|
|
||||||
bit, _ := strconv.ParseInt(n, 10, 64)
|
|
||||||
sum += bit << uint(24-8*i)
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum, nil
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
type LibraryInterface interface {
|
|
||||||
// 加载数据库文件
|
|
||||||
Load(dbPath string) error
|
|
||||||
|
|
||||||
// 查询IP
|
|
||||||
Lookup(ip string) (*Result, error)
|
|
||||||
|
|
||||||
// 关闭数据库文件
|
|
||||||
Close()
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type IP2RegionLibrary struct {
|
|
||||||
db *IP2Region
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *IP2RegionLibrary) Load(dbPath string) error {
|
|
||||||
db, err := NewIP2Region(dbPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
this.db = db
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *IP2RegionLibrary) Lookup(ip string) (*Result, error) {
|
|
||||||
if this.db == nil {
|
|
||||||
return nil, errors.New("library has not been loaded")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 只支持IPv4
|
|
||||||
if strings.Contains(ip, ":") {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if net.ParseIP(ip) == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
// 防止panic发生
|
|
||||||
err := recover()
|
|
||||||
if err != nil {
|
|
||||||
remotelogs.Error("IP2RegionLibrary", "panic: "+fmt.Sprintf("%#v", err))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
info, err := this.db.MemorySearch(ip)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.Country == "0" {
|
|
||||||
info.Country = ""
|
|
||||||
}
|
|
||||||
if info.Region == "0" {
|
|
||||||
info.Region = ""
|
|
||||||
}
|
|
||||||
if info.Province == "0" {
|
|
||||||
info.Province = ""
|
|
||||||
}
|
|
||||||
if info.City == "0" {
|
|
||||||
info.City = ""
|
|
||||||
}
|
|
||||||
if info.ISP == "0" {
|
|
||||||
info.ISP = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Result{
|
|
||||||
CityId: info.CityId,
|
|
||||||
Country: info.Country,
|
|
||||||
Region: info.Region,
|
|
||||||
Province: info.Province,
|
|
||||||
City: info.City,
|
|
||||||
ISP: info.ISP,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *IP2RegionLibrary) Close() {
|
|
||||||
if this.db != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/iwind/TeaGo/Tea"
|
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
|
||||||
"github.com/iwind/TeaGo/logs"
|
|
||||||
"github.com/iwind/TeaGo/rands"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestIP2RegionLibrary_Lookup(t *testing.T) {
|
|
||||||
library := &IP2RegionLibrary{}
|
|
||||||
err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
result, err := library.Lookup("114.240.223.47")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
logs.PrintAsJSON(result, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIP2RegionLibrary_Lookup_Valid_IP(t *testing.T) {
|
|
||||||
library := &IP2RegionLibrary{}
|
|
||||||
err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
result, err := library.Lookup("114.240.223")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
logs.PrintAsJSON(result, t)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
result, err := library.Lookup("abc")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
logs.PrintAsJSON(result, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func TestIP2RegionLibrary_Memory(t *testing.T) {
|
|
||||||
library := &IP2RegionLibrary{}
|
|
||||||
err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
before := time.Now()
|
|
||||||
|
|
||||||
for i := 0; i < 1_000_000; i++ {
|
|
||||||
_, _ = library.Lookup(strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)))
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkIP2RegionLibrary_Lookup(b *testing.B) {
|
|
||||||
runtime.GOMAXPROCS(1)
|
|
||||||
|
|
||||||
library := &IP2RegionLibrary{}
|
|
||||||
err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_, _ = library.Lookup(strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
|
||||||
"github.com/iwind/TeaGo/Tea"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"github.com/iwind/TeaGo/files"
|
|
||||||
"github.com/iwind/TeaGo/logs"
|
|
||||||
"github.com/iwind/TeaGo/types"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var SharedManager = NewManager()
|
|
||||||
var SharedLibrary LibraryInterface
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
dbs.OnReady(func() {
|
|
||||||
// 初始化
|
|
||||||
library, err := SharedManager.Load()
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[IP_LIBRARY]" + err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
SharedLibrary = library
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type Manager struct {
|
|
||||||
code string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewManager() *Manager {
|
|
||||||
return &Manager{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Manager) Load() (LibraryInterface, error) {
|
|
||||||
// 当前正在使用的IP库代号
|
|
||||||
config, err := models.SharedSysSettingDAO.ReadGlobalConfig(nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
code := config.IPLibrary.Code
|
|
||||||
if len(code) == 0 {
|
|
||||||
code = serverconfigs.DefaultIPLibraryType
|
|
||||||
}
|
|
||||||
|
|
||||||
dir := Tea.Root + "/resources/ipdata/" + code
|
|
||||||
var lastVersion int64 = -1
|
|
||||||
lastFilename := ""
|
|
||||||
for _, file := range files.NewFile(dir).List() {
|
|
||||||
filename := file.Name()
|
|
||||||
|
|
||||||
reg := regexp.MustCompile(`^` + regexp.QuoteMeta(code) + `.(\d+)\.`)
|
|
||||||
if reg.MatchString(filename) { // 先查找有版本号的
|
|
||||||
result := reg.FindStringSubmatch(filename)
|
|
||||||
version := types.Int64(result[1])
|
|
||||||
if version > lastVersion {
|
|
||||||
lastVersion = version
|
|
||||||
lastFilename = filename
|
|
||||||
}
|
|
||||||
} else if strings.HasPrefix(filename, code+".") { // 后查找默认的
|
|
||||||
if lastVersion == -1 {
|
|
||||||
lastFilename = filename
|
|
||||||
lastVersion = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(lastFilename) == 0 {
|
|
||||||
return nil, errors.New("ip library file not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
var libraryPtr LibraryInterface
|
|
||||||
switch code {
|
|
||||||
case serverconfigs.IPLibraryTypeIP2Region:
|
|
||||||
libraryPtr = &IP2RegionLibrary{}
|
|
||||||
default:
|
|
||||||
return nil, errors.New("invalid ip library code '" + code + "'")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = libraryPtr.Load(dir + "/" + lastFilename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return libraryPtr, nil
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestManager_Load(t *testing.T) {
|
|
||||||
dbs.NotifyReady()
|
|
||||||
|
|
||||||
manager := NewManager()
|
|
||||||
lib, err := manager.Load()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Log(lib.Lookup("1.2.3.4"))
|
|
||||||
t.Log(lib.Lookup("2.3.4.5"))
|
|
||||||
t.Log(lib.Lookup("200.200.200.200"))
|
|
||||||
t.Log(lib.Lookup("202.106.0.20"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewManager(t *testing.T) {
|
|
||||||
dbs.NotifyReady()
|
|
||||||
t.Log(SharedLibrary)
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/iwind/TeaGo/lists"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Result struct {
|
|
||||||
CityId int64
|
|
||||||
Country string
|
|
||||||
Region string
|
|
||||||
Province string
|
|
||||||
City string
|
|
||||||
ISP string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Result) Summary() string {
|
|
||||||
pieces := []string{}
|
|
||||||
if len(this.Country) > 0 {
|
|
||||||
pieces = append(pieces, this.Country)
|
|
||||||
}
|
|
||||||
if len(this.Province) > 0 && !lists.ContainsString(pieces, this.Province) {
|
|
||||||
pieces = append(pieces, this.Province)
|
|
||||||
}
|
|
||||||
if len(this.City) > 0 && !lists.ContainsString(pieces, this.City) && !lists.ContainsString(pieces, strings.TrimSuffix(this.City, "市")) {
|
|
||||||
pieces = append(pieces, this.City)
|
|
||||||
}
|
|
||||||
return strings.Join(pieces, " ")
|
|
||||||
}
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
|
||||||
"github.com/iwind/TeaGo/Tea"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"github.com/iwind/TeaGo/logs"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
dbs.OnReady(func() {
|
|
||||||
updater := NewUpdater()
|
|
||||||
updater.Start()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updater IP库更新程序
|
|
||||||
type Updater struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUpdater 获取新对象
|
|
||||||
func NewUpdater() *Updater {
|
|
||||||
return &Updater{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start 开始更新
|
|
||||||
func (this *Updater) Start() {
|
|
||||||
// 这里不需要太频繁检查更新,因为通常不需要更新IP库
|
|
||||||
ticker := time.NewTicker(1 * time.Hour)
|
|
||||||
goman.New(func() {
|
|
||||||
for range ticker.C {
|
|
||||||
err := this.loop()
|
|
||||||
if err != nil {
|
|
||||||
logs.Println("[IP_LIBRARY]" + err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 单次任务
|
|
||||||
func (this *Updater) loop() error {
|
|
||||||
config, err := models.SharedSysSettingDAO.ReadGlobalConfig(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
code := config.IPLibrary.Code
|
|
||||||
if len(code) == 0 {
|
|
||||||
code = serverconfigs.DefaultIPLibraryType
|
|
||||||
}
|
|
||||||
lib, err := models.SharedIPLibraryDAO.FindLatestIPLibraryWithType(nil, code)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if lib == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
typeInfo := serverconfigs.FindIPLibraryWithType(code)
|
|
||||||
if typeInfo == nil {
|
|
||||||
return errors.New("invalid ip library code '" + code + "'")
|
|
||||||
}
|
|
||||||
|
|
||||||
path := Tea.Root + "/resources/ipdata/" + code + "/" + code + "." + fmt.Sprintf("%d", lib.CreatedAt) + typeInfo.GetString("ext")
|
|
||||||
|
|
||||||
// 是否已经存在
|
|
||||||
_, err = os.Stat(path)
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 开始下载
|
|
||||||
chunkIds, err := models.SharedFileChunkDAO.FindAllFileChunkIds(nil, int64(lib.FileId))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
isOk := false
|
|
||||||
|
|
||||||
fp, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
// 如果保存不成功就直接删除
|
|
||||||
if !isOk {
|
|
||||||
_ = fp.Close()
|
|
||||||
_ = os.Remove(path)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
for _, chunkId := range chunkIds {
|
|
||||||
chunk, err := models.SharedFileChunkDAO.FindFileChunk(nil, chunkId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if chunk == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
_, err = fp.Write(chunk.Data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = fp.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重新加载
|
|
||||||
library, err := SharedManager.Load()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
SharedLibrary = library
|
|
||||||
|
|
||||||
isOk = true
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package iplibrary
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestUpdater_loop(t *testing.T) {
|
|
||||||
dbs.NotifyReady()
|
|
||||||
|
|
||||||
updater := NewUpdater()
|
|
||||||
err := updater.loop()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Log("ok")
|
|
||||||
}
|
|
||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc"
|
"github.com/TeaOSLab/EdgeAPI/internal/rpc"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/setup"
|
"github.com/TeaOSLab/EdgeAPI/internal/setup"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
"github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -86,6 +87,13 @@ func (this *APINode) Start() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 启动IP库
|
||||||
|
remotelogs.Println("API_NODE", "initializing ip library ...")
|
||||||
|
err = iplibrary.InitDefault()
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("API_NODE", "initialize ip library failed: "+err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
// 检查数据库连接
|
// 检查数据库连接
|
||||||
err = this.checkDB()
|
err = this.checkDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -569,7 +577,7 @@ func (this *APINode) listenPorts(apiNode *models.APINode) (isListening bool) {
|
|||||||
|
|
||||||
// add to local firewall
|
// add to local firewall
|
||||||
if len(ports) > 0 {
|
if len(ports) > 0 {
|
||||||
utils.AddPortsToFirewall(ports)
|
go utils.AddPortsToFirewall(ports)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -684,12 +692,12 @@ func (this *APINode) listenSock() error {
|
|||||||
|
|
||||||
err := this.sock.Listen()
|
err := this.sock.Listen()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Println("API_NODE", err.Error())
|
remotelogs.Println("API_NODE", err.Error())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
events.On(events.EventQuit, func() {
|
events.On(events.EventQuit, func() {
|
||||||
logs.Println("API_NODE", "quit unix sock")
|
remotelogs.Println("API_NODE", "quit unix sock")
|
||||||
_ = this.sock.Close()
|
_ = this.sock.Close()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -247,6 +247,11 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
|||||||
pb.RegisterIPLibraryFileServiceServer(server, instance)
|
pb.RegisterIPLibraryFileServiceServer(server, instance)
|
||||||
this.rest(instance)
|
this.rest(instance)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
var instance = this.serviceInstance(&services.IPLibraryArtifactService{}).(*services.IPLibraryArtifactService)
|
||||||
|
pb.RegisterIPLibraryArtifactServiceServer(server, instance)
|
||||||
|
this.rest(instance)
|
||||||
|
}
|
||||||
{
|
{
|
||||||
var instance = this.serviceInstance(&services.FileChunkService{}).(*services.FileChunkService)
|
var instance = this.serviceInstance(&services.FileChunkService{}).(*services.FileChunkService)
|
||||||
pb.RegisterFileChunkServiceServer(server, instance)
|
pb.RegisterFileChunkServiceServer(server, instance)
|
||||||
|
|||||||
105
internal/nodes/ip_library_updater.go
Normal file
105
internal/nodes/ip_library_updater.go
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
dbs.OnReady(func() {
|
||||||
|
goman.New(func() {
|
||||||
|
iplibrary.NewUpdater(NewIPLibraryUpdater(), 10*time.Minute).Start()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPLibraryUpdater struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIPLibraryUpdater() *IPLibraryUpdater {
|
||||||
|
return &IPLibraryUpdater{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataDir 文件目录
|
||||||
|
func (this *IPLibraryUpdater) DataDir() string {
|
||||||
|
// data/
|
||||||
|
var dir = Tea.Root + "/data"
|
||||||
|
stat, err := os.Stat(dir)
|
||||||
|
if err == nil && stat.IsDir() {
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Mkdir(dir, 0666)
|
||||||
|
if err == nil {
|
||||||
|
return dir
|
||||||
|
}
|
||||||
|
|
||||||
|
remotelogs.Error("IP_LIBRARY_UPDATER", "create directory '"+dir+"' failed: "+err.Error())
|
||||||
|
|
||||||
|
// 如果不能创建 data/ 目录,那么使用临时目录
|
||||||
|
return os.TempDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindLatestFile 检查最新的IP库文件
|
||||||
|
func (this *IPLibraryUpdater) FindLatestFile() (code string, fileId int64, err error) {
|
||||||
|
artifact, err := models.SharedIPLibraryArtifactDAO.FindPublicArtifact(nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
if artifact == nil {
|
||||||
|
return "", 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return artifact.Code, int64(artifact.FileId), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DownloadFile 下载文件
|
||||||
|
func (this *IPLibraryUpdater) DownloadFile(fileId int64, writer io.Writer) error {
|
||||||
|
if fileId <= 0 {
|
||||||
|
return errors.New("invalid fileId: " + types.String(fileId))
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx *dbs.Tx
|
||||||
|
chunkIds, err := models.SharedFileChunkDAO.FindAllFileChunkIds(tx, fileId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, chunkId := range chunkIds {
|
||||||
|
chunk, err := models.SharedFileChunkDAO.FindFileChunk(tx, chunkId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if chunk == nil {
|
||||||
|
return errors.New("can not find file chunk with chunk id '" + types.String(chunkId) + "'")
|
||||||
|
}
|
||||||
|
_, err = writer.Write(chunk.Data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogInfo 普通日志
|
||||||
|
func (this *IPLibraryUpdater) LogInfo(message string) {
|
||||||
|
remotelogs.Println("IP_LIBRARY_UPDATER", message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogError 错误日志
|
||||||
|
func (this *IPLibraryUpdater) LogError(err error) {
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
remotelogs.Error("IP_LIBRARY_UPDATER", err.Error())
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ type ACMEProviderService struct {
|
|||||||
|
|
||||||
// FindAllACMEProviders 查找所有的服务商
|
// FindAllACMEProviders 查找所有的服务商
|
||||||
func (this *ACMEProviderService) FindAllACMEProviders(ctx context.Context, req *pb.FindAllACMEProvidersRequest) (*pb.FindAllACMEProvidersResponse, error) {
|
func (this *ACMEProviderService) FindAllACMEProviders(ctx context.Context, req *pb.FindAllACMEProvidersRequest) (*pb.FindAllACMEProvidersResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, _, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ func (this *ACMEProviderService) FindAllACMEProviders(ctx context.Context, req *
|
|||||||
|
|
||||||
// FindACMEProviderWithCode 根据代号查找服务商
|
// FindACMEProviderWithCode 根据代号查找服务商
|
||||||
func (this *ACMEProviderService) FindACMEProviderWithCode(ctx context.Context, req *pb.FindACMEProviderWithCodeRequest) (*pb.FindACMEProviderWithCodeResponse, error) {
|
func (this *ACMEProviderService) FindACMEProviderWithCode(ctx context.Context, req *pb.FindACMEProviderWithCodeRequest) (*pb.FindACMEProviderWithCodeResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, _, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ type ACMEProviderAccountService struct {
|
|||||||
|
|
||||||
// CreateACMEProviderAccount 创建服务商账号
|
// CreateACMEProviderAccount 创建服务商账号
|
||||||
func (this *ACMEProviderAccountService) CreateACMEProviderAccount(ctx context.Context, req *pb.CreateACMEProviderAccountRequest) (*pb.CreateACMEProviderAccountResponse, error) {
|
func (this *ACMEProviderAccountService) CreateACMEProviderAccount(ctx context.Context, req *pb.CreateACMEProviderAccountRequest) (*pb.CreateACMEProviderAccountResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
accountId, err := acme.SharedACMEProviderAccountDAO.CreateAccount(tx, req.Name, req.ProviderCode, req.EabKid, req.EabKey)
|
accountId, err := acme.SharedACMEProviderAccountDAO.CreateAccount(tx, userId, req.Name, req.ProviderCode, req.EabKid, req.EabKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -33,13 +33,13 @@ func (this *ACMEProviderAccountService) CreateACMEProviderAccount(ctx context.Co
|
|||||||
|
|
||||||
// FindAllACMEProviderAccountsWithProviderCode 使用代号查找服务商账号
|
// FindAllACMEProviderAccountsWithProviderCode 使用代号查找服务商账号
|
||||||
func (this *ACMEProviderAccountService) FindAllACMEProviderAccountsWithProviderCode(ctx context.Context, req *pb.FindAllACMEProviderAccountsWithProviderCodeRequest) (*pb.FindAllACMEProviderAccountsWithProviderCodeResponse, error) {
|
func (this *ACMEProviderAccountService) FindAllACMEProviderAccountsWithProviderCode(ctx context.Context, req *pb.FindAllACMEProviderAccountsWithProviderCodeRequest) (*pb.FindAllACMEProviderAccountsWithProviderCodeResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
accounts, err := acme.SharedACMEProviderAccountDAO.FindAllEnabledAccountsWithProviderCode(tx, req.AcmeProviderCode)
|
accounts, err := acme.SharedACMEProviderAccountDAO.FindAllEnabledAccountsWithProviderCode(tx, userId, req.AcmeProviderCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -76,12 +76,21 @@ func (this *ACMEProviderAccountService) FindAllACMEProviderAccountsWithProviderC
|
|||||||
|
|
||||||
// UpdateACMEProviderAccount 修改服务商账号
|
// UpdateACMEProviderAccount 修改服务商账号
|
||||||
func (this *ACMEProviderAccountService) UpdateACMEProviderAccount(ctx context.Context, req *pb.UpdateACMEProviderAccountRequest) (*pb.RPCSuccess, error) {
|
func (this *ACMEProviderAccountService) UpdateACMEProviderAccount(ctx context.Context, req *pb.UpdateACMEProviderAccountRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// 检查权限
|
||||||
|
if userId > 0 {
|
||||||
|
err = acme.SharedACMEProviderAccountDAO.CheckUserAccount(tx, userId, req.AcmeProviderAccountId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = acme.SharedACMEProviderAccountDAO.UpdateAccount(tx, req.AcmeProviderAccountId, req.Name, req.EabKid, req.EabKey)
|
err = acme.SharedACMEProviderAccountDAO.UpdateAccount(tx, req.AcmeProviderAccountId, req.Name, req.EabKid, req.EabKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -91,12 +100,21 @@ func (this *ACMEProviderAccountService) UpdateACMEProviderAccount(ctx context.Co
|
|||||||
|
|
||||||
// DeleteACMEProviderAccount 删除服务商账号
|
// DeleteACMEProviderAccount 删除服务商账号
|
||||||
func (this *ACMEProviderAccountService) DeleteACMEProviderAccount(ctx context.Context, req *pb.DeleteACMEProviderAccountRequest) (*pb.RPCSuccess, error) {
|
func (this *ACMEProviderAccountService) DeleteACMEProviderAccount(ctx context.Context, req *pb.DeleteACMEProviderAccountRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// 检查权限
|
||||||
|
if userId > 0 {
|
||||||
|
err = acme.SharedACMEProviderAccountDAO.CheckUserAccount(tx, userId, req.AcmeProviderAccountId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = acme.SharedACMEProviderAccountDAO.DisableACMEProviderAccount(tx, req.AcmeProviderAccountId)
|
err = acme.SharedACMEProviderAccountDAO.DisableACMEProviderAccount(tx, req.AcmeProviderAccountId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -106,12 +124,21 @@ func (this *ACMEProviderAccountService) DeleteACMEProviderAccount(ctx context.Co
|
|||||||
|
|
||||||
// FindEnabledACMEProviderAccount 查找单个服务商账号
|
// FindEnabledACMEProviderAccount 查找单个服务商账号
|
||||||
func (this *ACMEProviderAccountService) FindEnabledACMEProviderAccount(ctx context.Context, req *pb.FindEnabledACMEProviderAccountRequest) (*pb.FindEnabledACMEProviderAccountResponse, error) {
|
func (this *ACMEProviderAccountService) FindEnabledACMEProviderAccount(ctx context.Context, req *pb.FindEnabledACMEProviderAccountRequest) (*pb.FindEnabledACMEProviderAccountResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// 检查权限
|
||||||
|
if userId > 0 {
|
||||||
|
err = acme.SharedACMEProviderAccountDAO.CheckUserAccount(tx, userId, req.AcmeProviderAccountId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
account, err := acme.SharedACMEProviderAccountDAO.FindEnabledACMEProviderAccount(tx, req.AcmeProviderAccountId)
|
account, err := acme.SharedACMEProviderAccountDAO.FindEnabledACMEProviderAccount(tx, req.AcmeProviderAccountId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -147,13 +174,13 @@ func (this *ACMEProviderAccountService) FindEnabledACMEProviderAccount(ctx conte
|
|||||||
|
|
||||||
// CountAllEnabledACMEProviderAccounts 计算所有服务商账号数量
|
// CountAllEnabledACMEProviderAccounts 计算所有服务商账号数量
|
||||||
func (this *ACMEProviderAccountService) CountAllEnabledACMEProviderAccounts(ctx context.Context, req *pb.CountAllEnabledACMEProviderAccountsRequest) (*pb.RPCCountResponse, error) {
|
func (this *ACMEProviderAccountService) CountAllEnabledACMEProviderAccounts(ctx context.Context, req *pb.CountAllEnabledACMEProviderAccountsRequest) (*pb.RPCCountResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
count, err := acme.SharedACMEProviderAccountDAO.CountAllEnabledAccounts(tx)
|
count, err := acme.SharedACMEProviderAccountDAO.CountAllEnabledAccounts(tx, userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -162,13 +189,13 @@ func (this *ACMEProviderAccountService) CountAllEnabledACMEProviderAccounts(ctx
|
|||||||
|
|
||||||
// ListEnabledACMEProviderAccounts 列出单页服务商账号
|
// ListEnabledACMEProviderAccounts 列出单页服务商账号
|
||||||
func (this *ACMEProviderAccountService) ListEnabledACMEProviderAccounts(ctx context.Context, req *pb.ListEnabledACMEProviderAccountsRequest) (*pb.ListEnabledACMEProviderAccountsResponse, error) {
|
func (this *ACMEProviderAccountService) ListEnabledACMEProviderAccounts(ctx context.Context, req *pb.ListEnabledACMEProviderAccountsRequest) (*pb.ListEnabledACMEProviderAccountsResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
accounts, err := acme.SharedACMEProviderAccountDAO.ListEnabledAccounts(tx, req.Offset, req.Size)
|
accounts, err := acme.SharedACMEProviderAccountDAO.ListEnabledAccounts(tx, userId, req.Offset, req.Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func (this *ACMETaskService) ListEnabledACMETasks(ctx context.Context, req *pb.L
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := []*pb.ACMETask{}
|
var result = []*pb.ACMETask{}
|
||||||
for _, task := range tasks {
|
for _, task := range tasks {
|
||||||
// ACME用户
|
// ACME用户
|
||||||
acmeUser, err := acmemodels.SharedACMEUserDAO.FindEnabledACMEUser(tx, int64(task.AcmeUserId))
|
acmeUser, err := acmemodels.SharedACMEUserDAO.FindEnabledACMEUser(tx, int64(task.AcmeUserId))
|
||||||
|
|||||||
@@ -417,9 +417,10 @@ func (this *DNSDomainService) convertRecordToPB(record *dnstypes.Record) *pb.DNS
|
|||||||
|
|
||||||
// 检查集群节点变化
|
// 检查集群节点变化
|
||||||
func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster, records []*dnstypes.Record, domainName string, defaultRoute string) (result []maps.Map, doneNodeRecords []*dnstypes.Record, doneServerRecords []*dnstypes.Record, countAllNodes int64, countAllServers int64, nodesChanged bool, serversChanged bool, err error) {
|
func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster, records []*dnstypes.Record, domainName string, defaultRoute string) (result []maps.Map, doneNodeRecords []*dnstypes.Record, doneServerRecords []*dnstypes.Record, countAllNodes int64, countAllServers int64, nodesChanged bool, serversChanged bool, err error) {
|
||||||
clusterId := int64(cluster.Id)
|
var clusterId = int64(cluster.Id)
|
||||||
clusterDnsName := cluster.DnsName
|
var clusterDnsName = cluster.DnsName
|
||||||
clusterDomain := clusterDnsName + "." + domainName
|
var clusterDomain = clusterDnsName + "." + domainName
|
||||||
|
var dnsConfig, _ = cluster.DecodeDNSConfig()
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
@@ -437,7 +438,7 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 节点域名
|
// 节点域名
|
||||||
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true)
|
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true, dnsConfig != nil && dnsConfig.IncludingLnNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, 0, 0, false, false, err
|
return nil, nil, nil, 0, 0, false, false, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func (this *FileChunkService) CreateFileChunk(ctx context.Context, req *pb.Creat
|
|||||||
// FindAllFileChunkIds 获取的一个文件的所有片段IDs
|
// FindAllFileChunkIds 获取的一个文件的所有片段IDs
|
||||||
func (this *FileChunkService) FindAllFileChunkIds(ctx context.Context, req *pb.FindAllFileChunkIdsRequest) (*pb.FindAllFileChunkIdsResponse, error) {
|
func (this *FileChunkService) FindAllFileChunkIds(ctx context.Context, req *pb.FindAllFileChunkIdsRequest) (*pb.FindAllFileChunkIdsResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser)
|
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ func (this *FileChunkService) FindAllFileChunkIds(ctx context.Context, req *pb.F
|
|||||||
// DownloadFileChunk 下载文件片段
|
// DownloadFileChunk 下载文件片段
|
||||||
func (this *FileChunkService) DownloadFileChunk(ctx context.Context, req *pb.DownloadFileChunkRequest) (*pb.DownloadFileChunkResponse, error) {
|
func (this *FileChunkService) DownloadFileChunk(ctx context.Context, req *pb.DownloadFileChunkRequest) (*pb.DownloadFileChunkResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser)
|
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ type HTTPAuthPolicyService struct {
|
|||||||
|
|
||||||
// CreateHTTPAuthPolicy 创建策略
|
// CreateHTTPAuthPolicy 创建策略
|
||||||
func (this *HTTPAuthPolicyService) CreateHTTPAuthPolicy(ctx context.Context, req *pb.CreateHTTPAuthPolicyRequest) (*pb.CreateHTTPAuthPolicyResponse, error) {
|
func (this *HTTPAuthPolicyService) CreateHTTPAuthPolicy(ctx context.Context, req *pb.CreateHTTPAuthPolicyRequest) (*pb.CreateHTTPAuthPolicyResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
policyId, err := models.SharedHTTPAuthPolicyDAO.CreateHTTPAuthPolicy(tx, req.Name, req.Type, req.ParamsJSON)
|
policyId, err := models.SharedHTTPAuthPolicyDAO.CreateHTTPAuthPolicy(tx, userId, req.Name, req.Type, req.ParamsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,12 +30,21 @@ func (this *HTTPAuthPolicyService) CreateHTTPAuthPolicy(ctx context.Context, req
|
|||||||
|
|
||||||
// UpdateHTTPAuthPolicy 修改策略
|
// UpdateHTTPAuthPolicy 修改策略
|
||||||
func (this *HTTPAuthPolicyService) UpdateHTTPAuthPolicy(ctx context.Context, req *pb.UpdateHTTPAuthPolicyRequest) (*pb.RPCSuccess, error) {
|
func (this *HTTPAuthPolicyService) UpdateHTTPAuthPolicy(ctx context.Context, req *pb.UpdateHTTPAuthPolicyRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// 检查用户权限
|
||||||
|
if userId > 0 {
|
||||||
|
err = models.SharedHTTPAuthPolicyDAO.CheckUserPolicy(tx, userId, req.HttpAuthPolicyId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = models.SharedHTTPAuthPolicyDAO.UpdateHTTPAuthPolicy(tx, req.HttpAuthPolicyId, req.Name, req.ParamsJSON, req.IsOn)
|
err = models.SharedHTTPAuthPolicyDAO.UpdateHTTPAuthPolicy(tx, req.HttpAuthPolicyId, req.Name, req.ParamsJSON, req.IsOn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -45,12 +54,21 @@ func (this *HTTPAuthPolicyService) UpdateHTTPAuthPolicy(ctx context.Context, req
|
|||||||
|
|
||||||
// FindEnabledHTTPAuthPolicy 查找策略信息
|
// FindEnabledHTTPAuthPolicy 查找策略信息
|
||||||
func (this *HTTPAuthPolicyService) FindEnabledHTTPAuthPolicy(ctx context.Context, req *pb.FindEnabledHTTPAuthPolicyRequest) (*pb.FindEnabledHTTPAuthPolicyResponse, error) {
|
func (this *HTTPAuthPolicyService) FindEnabledHTTPAuthPolicy(ctx context.Context, req *pb.FindEnabledHTTPAuthPolicyRequest) (*pb.FindEnabledHTTPAuthPolicyResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// 检查用户权限
|
||||||
|
if userId > 0 {
|
||||||
|
err = models.SharedHTTPAuthPolicyDAO.CheckUserPolicy(tx, userId, req.HttpAuthPolicyId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
policy, err := models.SharedHTTPAuthPolicyDAO.FindEnabledHTTPAuthPolicy(tx, req.HttpAuthPolicyId)
|
policy, err := models.SharedHTTPAuthPolicyDAO.FindEnabledHTTPAuthPolicy(tx, req.HttpAuthPolicyId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/iplibrary"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
@@ -794,20 +793,14 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查封禁的地区和省份
|
// 检查封禁的地区和省份
|
||||||
info, err := iplibrary.SharedLibrary.Lookup(req.Ip)
|
var info = iplibrary.LookupIP(req.Ip)
|
||||||
if err != nil {
|
if info != nil && info.IsOk() {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if info != nil {
|
|
||||||
if firewallPolicy.Inbound != nil &&
|
if firewallPolicy.Inbound != nil &&
|
||||||
firewallPolicy.Inbound.IsOn &&
|
firewallPolicy.Inbound.IsOn &&
|
||||||
firewallPolicy.Inbound.Region != nil &&
|
firewallPolicy.Inbound.Region != nil &&
|
||||||
firewallPolicy.Inbound.Region.IsOn {
|
firewallPolicy.Inbound.Region.IsOn {
|
||||||
// 检查封禁的地区
|
// 检查封禁的地区
|
||||||
countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithNameCacheable(tx, info.Country)
|
var countryId = info.CountryId()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if countryId > 0 && lists.ContainsInt64(firewallPolicy.Inbound.Region.DenyCountryIds, countryId) {
|
if countryId > 0 && lists.ContainsInt64(firewallPolicy.Inbound.Region.DenyCountryIds, countryId) {
|
||||||
return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
|
return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
|
||||||
IsOk: true,
|
IsOk: true,
|
||||||
@@ -818,7 +811,7 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
|||||||
IpItem: nil,
|
IpItem: nil,
|
||||||
RegionCountry: &pb.RegionCountry{
|
RegionCountry: &pb.RegionCountry{
|
||||||
Id: countryId,
|
Id: countryId,
|
||||||
Name: info.Country,
|
Name: info.CountryName(),
|
||||||
},
|
},
|
||||||
RegionProvince: nil,
|
RegionProvince: nil,
|
||||||
}, nil
|
}, nil
|
||||||
@@ -826,10 +819,7 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
|||||||
|
|
||||||
// 检查封禁的省份
|
// 检查封禁的省份
|
||||||
if countryId > 0 {
|
if countryId > 0 {
|
||||||
provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithNameCacheable(tx, countryId, info.Province)
|
var provinceId = info.ProvinceId()
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if provinceId > 0 && lists.ContainsInt64(firewallPolicy.Inbound.Region.DenyProvinceIds, provinceId) {
|
if provinceId > 0 && lists.ContainsInt64(firewallPolicy.Inbound.Region.DenyProvinceIds, provinceId) {
|
||||||
return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
|
return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
|
||||||
IsOk: true,
|
IsOk: true,
|
||||||
@@ -840,11 +830,11 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
|
|||||||
IpItem: nil,
|
IpItem: nil,
|
||||||
RegionCountry: &pb.RegionCountry{
|
RegionCountry: &pb.RegionCountry{
|
||||||
Id: countryId,
|
Id: countryId,
|
||||||
Name: info.Country,
|
Name: info.CountryName(),
|
||||||
},
|
},
|
||||||
RegionProvince: &pb.RegionProvince{
|
RegionProvince: &pb.RegionProvince{
|
||||||
Id: provinceId,
|
Id: provinceId,
|
||||||
Name: info.Province,
|
Name: info.ProvinceName(),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -663,13 +663,20 @@ func (this *HTTPWebService) UpdateHTTPWebCommon(ctx context.Context, req *pb.Upd
|
|||||||
|
|
||||||
// UpdateHTTPWebRequestLimit 修改请求限制
|
// UpdateHTTPWebRequestLimit 修改请求限制
|
||||||
func (this *HTTPWebService) UpdateHTTPWebRequestLimit(ctx context.Context, req *pb.UpdateHTTPWebRequestLimitRequest) (*pb.RPCSuccess, error) {
|
func (this *HTTPWebService) UpdateHTTPWebRequestLimit(ctx context.Context, req *pb.UpdateHTTPWebRequestLimitRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
if userId > 0 {
|
||||||
|
err = models.SharedHTTPWebDAO.CheckUserWeb(tx, userId, req.HttpWebId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var config = &serverconfigs.HTTPRequestLimitConfig{}
|
var config = &serverconfigs.HTTPRequestLimitConfig{}
|
||||||
err = json.Unmarshal(req.RequestLimitJSON, config)
|
err = json.Unmarshal(req.RequestLimitJSON, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ package services
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/iplibrary"
|
|
||||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -183,34 +182,19 @@ func (this *IPLibraryService) LookupIPRegion(ctx context.Context, req *pb.Lookup
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := iplibrary.SharedLibrary.Lookup(req.Ip)
|
var result = iplibrary.LookupIP(req.Ip)
|
||||||
if err != nil {
|
if result == nil || !result.IsOk() {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if result == nil {
|
|
||||||
return &pb.LookupIPRegionResponse{IpRegion: nil}, nil
|
return &pb.LookupIPRegionResponse{IpRegion: nil}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithNameCacheable(tx, result.Country)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithNameCacheable(tx, countryId, result.Province)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.LookupIPRegionResponse{IpRegion: &pb.IPRegion{
|
return &pb.LookupIPRegionResponse{IpRegion: &pb.IPRegion{
|
||||||
Country: result.Country,
|
Country: result.CountryName(),
|
||||||
Region: result.Region,
|
Region: "",
|
||||||
Province: result.Province,
|
Province: result.ProvinceName(),
|
||||||
City: result.City,
|
City: result.CityName(),
|
||||||
Isp: result.ISP,
|
Isp: result.ProviderName(),
|
||||||
CountryId: countryId,
|
CountryId: result.CountryId(),
|
||||||
ProvinceId: provinceId,
|
ProvinceId: result.ProvinceId(),
|
||||||
Summary: result.Summary(),
|
Summary: result.Summary(),
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
@@ -223,20 +207,17 @@ func (this *IPLibraryService) LookupIPRegions(ctx context.Context, req *pb.Looku
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := map[string]*pb.IPRegion{}
|
var result = map[string]*pb.IPRegion{}
|
||||||
if len(req.IpList) > 0 {
|
if len(req.IpList) > 0 {
|
||||||
for _, ip := range req.IpList {
|
for _, ip := range req.IpList {
|
||||||
info, err := iplibrary.SharedLibrary.Lookup(ip)
|
var info = iplibrary.LookupIP(ip)
|
||||||
if err != nil {
|
if info != nil && info.IsOk() {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if info != nil {
|
|
||||||
result[ip] = &pb.IPRegion{
|
result[ip] = &pb.IPRegion{
|
||||||
Country: info.Country,
|
Country: info.CountryName(),
|
||||||
Region: info.Region,
|
Region: "",
|
||||||
Province: info.Province,
|
Province: info.ProvinceName(),
|
||||||
City: info.City,
|
City: info.CityName(),
|
||||||
Isp: info.ISP,
|
Isp: info.ProviderName(),
|
||||||
Summary: info.Summary(),
|
Summary: info.Summary(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
166
internal/rpc/services/service_ip_library_artifact.go
Normal file
166
internal/rpc/services/service_ip_library_artifact.go
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPLibraryArtifactService IP库制品
|
||||||
|
type IPLibraryArtifactService struct {
|
||||||
|
BaseService
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateIPLibraryArtifact 创建制品
|
||||||
|
func (this *IPLibraryArtifactService) CreateIPLibraryArtifact(ctx context.Context, req *pb.CreateIPLibraryArtifactRequest) (*pb.CreateIPLibraryArtifactResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
var meta = &iplibrary.Meta{}
|
||||||
|
err = json.Unmarshal(req.MetaJSON, meta)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("decode meta failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 更新数据库中的省市县等信息?
|
||||||
|
|
||||||
|
artifactId, err := models.SharedIPLibraryArtifactDAO.CreateArtifact(tx, req.Name, req.FileId, 0, meta)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pb.CreateIPLibraryArtifactResponse{IpLibraryArtifactId: artifactId}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateIPLibraryArtifactIsPublic 使用/取消使用制品
|
||||||
|
func (this *IPLibraryArtifactService) UpdateIPLibraryArtifactIsPublic(ctx context.Context, req *pb.UpdateIPLibraryArtifactIsPublicRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
err = models.SharedIPLibraryArtifactDAO.UpdateArtifactPublic(tx, req.IpLibraryArtifactId, req.IsPublic)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllIPLibraryArtifacts 查询所有制品
|
||||||
|
func (this *IPLibraryArtifactService) FindAllIPLibraryArtifacts(ctx context.Context, req *pb.FindAllIPLibraryArtifactsRequest) (*pb.FindAllIPLibraryArtifactsResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
artifacts, err := models.SharedIPLibraryArtifactDAO.FindAllArtifacts(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pbArtifacts = []*pb.IPLibraryArtifact{}
|
||||||
|
for _, artifact := range artifacts {
|
||||||
|
pbArtifacts = append(pbArtifacts, &pb.IPLibraryArtifact{
|
||||||
|
Id: int64(artifact.Id),
|
||||||
|
Name: artifact.Name,
|
||||||
|
FileId: int64(artifact.FileId),
|
||||||
|
CreatedAt: int64(artifact.CreatedAt),
|
||||||
|
MetaJSON: artifact.Meta,
|
||||||
|
IsPublic: artifact.IsPublic,
|
||||||
|
Code: artifact.Code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return &pb.FindAllIPLibraryArtifactsResponse{
|
||||||
|
IpLibraryArtifacts: pbArtifacts,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindIPLibraryArtifact 查找当前正在使用的制品
|
||||||
|
func (this *IPLibraryArtifactService) FindIPLibraryArtifact(ctx context.Context, req *pb.FindIPLibraryArtifactRequest) (*pb.FindIPLibraryArtifactResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
artifact, err := models.SharedIPLibraryArtifactDAO.FindEnabledIPLibraryArtifact(tx, req.IpLibraryArtifactId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if artifact == nil {
|
||||||
|
return &pb.FindIPLibraryArtifactResponse{
|
||||||
|
IpLibraryArtifact: nil,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindIPLibraryArtifactResponse{
|
||||||
|
IpLibraryArtifact: &pb.IPLibraryArtifact{
|
||||||
|
Id: int64(artifact.Id),
|
||||||
|
FileId: int64(artifact.FileId),
|
||||||
|
CreatedAt: int64(artifact.CreatedAt),
|
||||||
|
MetaJSON: artifact.Meta,
|
||||||
|
IsPublic: artifact.IsPublic,
|
||||||
|
Code: artifact.Code,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindPublicIPLibraryArtifact 查找当前正在使用的制品
|
||||||
|
func (this *IPLibraryArtifactService) FindPublicIPLibraryArtifact(ctx context.Context, req *pb.FindPublicIPLibraryArtifactRequest) (*pb.FindPublicIPLibraryArtifactResponse, error) {
|
||||||
|
_, _, err := this.ValidateNodeId(ctx, rpcutils.UserTypeNode, rpcutils.UserTypeDNS)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
artifact, err := models.SharedIPLibraryArtifactDAO.FindPublicArtifact(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if artifact == nil {
|
||||||
|
return &pb.FindPublicIPLibraryArtifactResponse{
|
||||||
|
IpLibraryArtifact: nil,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindPublicIPLibraryArtifactResponse{
|
||||||
|
IpLibraryArtifact: &pb.IPLibraryArtifact{
|
||||||
|
Id: int64(artifact.Id),
|
||||||
|
FileId: int64(artifact.FileId),
|
||||||
|
CreatedAt: int64(artifact.CreatedAt),
|
||||||
|
MetaJSON: artifact.Meta,
|
||||||
|
IsPublic: artifact.IsPublic,
|
||||||
|
Code: artifact.Code,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIPLibraryArtifact 删除制品
|
||||||
|
func (this *IPLibraryArtifactService) DeleteIPLibraryArtifact(ctx context.Context, req *pb.DeleteIPLibraryArtifactRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
err = models.SharedIPLibraryArtifactDAO.DisableIPLibraryArtifact(tx, req.IpLibraryArtifactId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
@@ -18,6 +18,71 @@ type IPLibraryFileService struct {
|
|||||||
BaseService
|
BaseService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAllFinishedIPLibraryFiles 查找所有已完成的IP库文件
|
||||||
|
func (this *IPLibraryFileService) FindAllFinishedIPLibraryFiles(ctx context.Context, req *pb.FindAllFinishedIPLibraryFilesRequest) (*pb.FindAllFinishedIPLibraryFilesResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
libraryFiles, err := models.SharedIPLibraryFileDAO.FindAllFinishedLibraryFiles(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var pbLibraryFiles = []*pb.IPLibraryFile{}
|
||||||
|
for _, libraryFile := range libraryFiles {
|
||||||
|
var pbCountryNames = libraryFile.DecodeCountries()
|
||||||
|
var pbProviderNames = libraryFile.DecodeProviders()
|
||||||
|
|
||||||
|
var pbProvinces = []*pb.IPLibraryFile_Province{}
|
||||||
|
for _, province := range libraryFile.DecodeProvinces() {
|
||||||
|
pbProvinces = append(pbProvinces, &pb.IPLibraryFile_Province{
|
||||||
|
CountryName: province[0],
|
||||||
|
ProvinceName: province[1],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var pbCities = []*pb.IPLibraryFile_City{}
|
||||||
|
for _, city := range libraryFile.DecodeCities() {
|
||||||
|
pbCities = append(pbCities, &pb.IPLibraryFile_City{
|
||||||
|
CountryName: city[0],
|
||||||
|
ProvinceName: city[1],
|
||||||
|
CityName: city[2],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var pbTowns = []*pb.IPLibraryFile_Town{}
|
||||||
|
for _, town := range libraryFile.DecodeTowns() {
|
||||||
|
pbTowns = append(pbTowns, &pb.IPLibraryFile_Town{
|
||||||
|
CountryName: town[0],
|
||||||
|
ProvinceName: town[1],
|
||||||
|
CityName: town[2],
|
||||||
|
TownName: town[3],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pbLibraryFiles = append(pbLibraryFiles, &pb.IPLibraryFile{
|
||||||
|
Id: int64(libraryFile.Id),
|
||||||
|
Name: libraryFile.Name,
|
||||||
|
FileId: int64(libraryFile.FileId),
|
||||||
|
IsFinished: libraryFile.IsFinished,
|
||||||
|
CreatedAt: int64(libraryFile.CreatedAt),
|
||||||
|
GeneratedFileId: int64(libraryFile.GeneratedFileId),
|
||||||
|
GeneratedAt: int64(libraryFile.GeneratedAt),
|
||||||
|
CountryNames: pbCountryNames,
|
||||||
|
Provinces: pbProvinces,
|
||||||
|
Cities: pbCities,
|
||||||
|
Towns: pbTowns,
|
||||||
|
ProviderNames: pbProviderNames,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindAllFinishedIPLibraryFilesResponse{
|
||||||
|
IpLibraryFiles: pbLibraryFiles,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FindAllUnfinishedIPLibraryFiles 查找所有未完成的IP库文件
|
// FindAllUnfinishedIPLibraryFiles 查找所有未完成的IP库文件
|
||||||
func (this *IPLibraryFileService) FindAllUnfinishedIPLibraryFiles(ctx context.Context, req *pb.FindAllUnfinishedIPLibraryFilesRequest) (*pb.FindAllUnfinishedIPLibraryFilesResponse, error) {
|
func (this *IPLibraryFileService) FindAllUnfinishedIPLibraryFiles(ctx context.Context, req *pb.FindAllUnfinishedIPLibraryFilesRequest) (*pb.FindAllUnfinishedIPLibraryFilesResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, err := this.ValidateAdmin(ctx)
|
||||||
@@ -64,6 +129,7 @@ func (this *IPLibraryFileService) FindAllUnfinishedIPLibraryFiles(ctx context.Co
|
|||||||
|
|
||||||
pbLibraryFiles = append(pbLibraryFiles, &pb.IPLibraryFile{
|
pbLibraryFiles = append(pbLibraryFiles, &pb.IPLibraryFile{
|
||||||
Id: int64(libraryFile.Id),
|
Id: int64(libraryFile.Id),
|
||||||
|
Name: libraryFile.Name,
|
||||||
FileId: int64(libraryFile.FileId),
|
FileId: int64(libraryFile.FileId),
|
||||||
IsFinished: libraryFile.IsFinished,
|
IsFinished: libraryFile.IsFinished,
|
||||||
CreatedAt: int64(libraryFile.CreatedAt),
|
CreatedAt: int64(libraryFile.CreatedAt),
|
||||||
@@ -130,15 +196,19 @@ func (this *IPLibraryFileService) FindIPLibraryFile(ctx context.Context, req *pb
|
|||||||
|
|
||||||
return &pb.FindIPLibraryFileResponse{
|
return &pb.FindIPLibraryFileResponse{
|
||||||
IpLibraryFile: &pb.IPLibraryFile{
|
IpLibraryFile: &pb.IPLibraryFile{
|
||||||
Id: int64(libraryFile.Id),
|
Id: int64(libraryFile.Id),
|
||||||
FileId: int64(libraryFile.FileId),
|
Name: libraryFile.Name,
|
||||||
IsFinished: libraryFile.IsFinished,
|
Template: libraryFile.Template,
|
||||||
CreatedAt: int64(libraryFile.CreatedAt),
|
EmptyValues: libraryFile.DecodeEmptyValues(),
|
||||||
CountryNames: pbCountryNames,
|
FileId: int64(libraryFile.FileId),
|
||||||
Provinces: pbProvinces,
|
IsFinished: libraryFile.IsFinished,
|
||||||
Cities: pbCities,
|
CreatedAt: int64(libraryFile.CreatedAt),
|
||||||
Towns: pbTowns,
|
GeneratedFileId: int64(libraryFile.GeneratedFileId),
|
||||||
ProviderNames: pbProviderNames,
|
CountryNames: pbCountryNames,
|
||||||
|
Provinces: pbProvinces,
|
||||||
|
Cities: pbCities,
|
||||||
|
Towns: pbTowns,
|
||||||
|
ProviderNames: pbProviderNames,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -182,7 +252,7 @@ func (this *IPLibraryFileService) CreateIPLibraryFile(ctx context.Context, req *
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
libraryFileId, err := models.SharedIPLibraryFileDAO.CreateLibraryFile(tx, req.Template, req.EmptyValues, req.FileId, countries, provinces, cities, towns, providers)
|
libraryFileId, err := models.SharedIPLibraryFileDAO.CreateLibraryFile(tx, req.Name, req.Template, req.EmptyValues, req.FileId, countries, provinces, cities, towns, providers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -481,6 +551,9 @@ func (this *IPLibraryFileService) CheckTownsWithIPLibraryFileId(ctx context.Cont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cityMap[cityKey] = cityId
|
cityMap[cityKey] = cityId
|
||||||
|
if cityId > 0 {
|
||||||
|
cityIds = append(cityIds, cityId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// town
|
// town
|
||||||
@@ -607,3 +680,34 @@ func (this *IPLibraryFileService) GenerateIPLibraryFile(ctx context.Context, req
|
|||||||
|
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateIPLibraryFileFinished 设置某个IP库为已完成
|
||||||
|
func (this *IPLibraryFileService) UpdateIPLibraryFileFinished(ctx context.Context, req *pb.UpdateIPLibraryFileFinishedRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedIPLibraryFileDAO.UpdateLibraryFileIsFinished(tx, req.IpLibraryFileId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteIPLibraryFile 删除IP库文件
|
||||||
|
func (this *IPLibraryFileService) DeleteIPLibraryFile(ctx context.Context, req *pb.DeleteIPLibraryFileRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedIPLibraryFileDAO.DisableIPLibraryFile(tx, req.IpLibraryFileId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ func init() {
|
|||||||
var countKeys = 0
|
var countKeys = 0
|
||||||
for key := range metricStatKeysQueue {
|
for key := range metricStatKeysQueue {
|
||||||
err := func(key string) error {
|
err := func(key string) error {
|
||||||
var tx *dbs.Tx
|
|
||||||
|
|
||||||
metricStatsLocker.Lock()
|
metricStatsLocker.Lock()
|
||||||
req, ok := metricStatsMap[key]
|
req, ok := metricStatsMap[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -45,7 +43,20 @@ func init() {
|
|||||||
var itemId = types.Int64(pieces[3])
|
var itemId = types.Int64(pieces[3])
|
||||||
|
|
||||||
// 删除旧的数据
|
// 删除旧的数据
|
||||||
err := models.SharedMetricStatDAO.DeleteNodeItemStats(tx, nodeId, serverId, itemId, req.Time)
|
tx, err := models.SharedMetricStatDAO.Instance.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
// 失败时不需要rollback
|
||||||
|
commitErr := tx.Commit()
|
||||||
|
if commitErr != nil {
|
||||||
|
remotelogs.Error("METRIC_STAT", "commit metric stats failed: "+commitErr.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = models.SharedMetricStatDAO.DeleteNodeItemStats(tx, nodeId, serverId, itemId, req.Time)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -475,7 +475,7 @@ func (this *NodeService) UpdateNode(ctx context.Context, req *pb.UpdateNodeReque
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedNodeDAO.UpdateNode(tx, req.NodeId, req.Name, req.NodeClusterId, req.SecondaryNodeClusterIds, req.NodeGroupId, req.NodeRegionId, req.IsOn, int(req.Level))
|
err = models.SharedNodeDAO.UpdateNode(tx, req.NodeId, req.Name, req.NodeClusterId, req.SecondaryNodeClusterIds, req.NodeGroupId, req.NodeRegionId, req.IsOn, int(req.Level), req.LnAddrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -673,6 +673,7 @@ func (this *NodeService) FindEnabledNode(ctx context.Context, req *pb.FindEnable
|
|||||||
MaxCacheMemoryCapacity: pbMaxCacheMemoryCapacity,
|
MaxCacheMemoryCapacity: pbMaxCacheMemoryCapacity,
|
||||||
CacheDiskDir: node.CacheDiskDir,
|
CacheDiskDir: node.CacheDiskDir,
|
||||||
Level: int32(node.Level),
|
Level: int32(node.Level),
|
||||||
|
LnAddrs: node.DecodeLnAddrs(),
|
||||||
DnsRoutes: pbRoutes,
|
DnsRoutes: pbRoutes,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
@@ -1304,18 +1305,19 @@ func (this *NodeService) FindAllEnabledNodesDNSWithNodeClusterId(ctx context.Con
|
|||||||
if clusterDNS == nil {
|
if clusterDNS == nil {
|
||||||
return nil, errors.New("not found clusterId '" + numberutils.FormatInt64(req.NodeClusterId) + "'")
|
return nil, errors.New("not found clusterId '" + numberutils.FormatInt64(req.NodeClusterId) + "'")
|
||||||
}
|
}
|
||||||
dnsDomainId := int64(clusterDNS.DnsDomainId)
|
var dnsConfig, _ = clusterDNS.DecodeDNSConfig()
|
||||||
|
var dnsDomainId = int64(clusterDNS.DnsDomainId)
|
||||||
|
|
||||||
routes, err := dns.SharedDNSDomainDAO.FindDomainRoutes(tx, dnsDomainId)
|
routes, err := dns.SharedDNSDomainDAO.FindDomainRoutes(tx, dnsDomainId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, req.NodeClusterId, true)
|
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, req.NodeClusterId, true, dnsConfig != nil && dnsConfig.IncludingLnNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := []*pb.NodeDNSInfo{}
|
var result = []*pb.NodeDNSInfo{}
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
ipAddresses, err := models.SharedNodeIPAddressDAO.FindNodeAccessAndUpIPAddresses(tx, int64(node.Id), nodeconfigs.NodeRoleNode)
|
ipAddresses, err := models.SharedNodeIPAddressDAO.FindNodeAccessAndUpIPAddresses(tx, int64(node.Id), nodeconfigs.NodeRoleNode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1327,7 +1329,7 @@ func (this *NodeService) FindAllEnabledNodesDNSWithNodeClusterId(ctx context.Con
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pbRoutes := []*pb.DNSRoute{}
|
var pbRoutes = []*pb.DNSRoute{}
|
||||||
for _, routeCode := range domainRouteCodes {
|
for _, routeCode := range domainRouteCodes {
|
||||||
for _, r := range routes {
|
for _, r := range routes {
|
||||||
if r.Code == routeCode {
|
if r.Code == routeCode {
|
||||||
@@ -1868,7 +1870,7 @@ func (this *NodeService) FindNodeDDoSProtection(ctx context.Context, req *pb.Fin
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNodeDDoSProtection 修改集群的DDOS设置
|
// UpdateNodeDDoSProtection 修改集群的DDoS设置
|
||||||
func (this *NodeService) UpdateNodeDDoSProtection(ctx context.Context, req *pb.UpdateNodeDDoSProtectionRequest) (*pb.RPCSuccess, error) {
|
func (this *NodeService) UpdateNodeDDoSProtection(ctx context.Context, req *pb.UpdateNodeDDoSProtectionRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, err := this.ValidateAdmin(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -450,14 +450,15 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r
|
|||||||
|
|
||||||
if dnsInfo.DnsDomainId == 0 {
|
if dnsInfo.DnsDomainId == 0 {
|
||||||
return &pb.FindEnabledNodeClusterDNSResponse{
|
return &pb.FindEnabledNodeClusterDNSResponse{
|
||||||
Name: dnsInfo.DnsName,
|
Name: dnsInfo.DnsName,
|
||||||
Domain: nil,
|
Domain: nil,
|
||||||
Provider: nil,
|
Provider: nil,
|
||||||
NodesAutoSync: dnsConfig.NodesAutoSync,
|
NodesAutoSync: dnsConfig.NodesAutoSync,
|
||||||
ServersAutoSync: dnsConfig.ServersAutoSync,
|
ServersAutoSync: dnsConfig.ServersAutoSync,
|
||||||
CnameRecords: dnsConfig.CNameRecords,
|
CnameRecords: dnsConfig.CNameRecords,
|
||||||
Ttl: dnsConfig.TTL,
|
Ttl: dnsConfig.TTL,
|
||||||
CnameAsDomain: dnsConfig.CNameAsDomain,
|
CnameAsDomain: dnsConfig.CNameAsDomain,
|
||||||
|
IncludingLnNodes: dnsConfig.IncludingLnNodes,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,15 +510,16 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindEnabledNodeClusterDNSResponse{
|
return &pb.FindEnabledNodeClusterDNSResponse{
|
||||||
Name: dnsInfo.DnsName,
|
Name: dnsInfo.DnsName,
|
||||||
Domain: pbDomain,
|
Domain: pbDomain,
|
||||||
Provider: pbProvider,
|
Provider: pbProvider,
|
||||||
NodesAutoSync: dnsConfig.NodesAutoSync,
|
NodesAutoSync: dnsConfig.NodesAutoSync,
|
||||||
ServersAutoSync: dnsConfig.ServersAutoSync,
|
ServersAutoSync: dnsConfig.ServersAutoSync,
|
||||||
CnameRecords: dnsConfig.CNameRecords,
|
CnameRecords: dnsConfig.CNameRecords,
|
||||||
Ttl: dnsConfig.TTL,
|
Ttl: dnsConfig.TTL,
|
||||||
CnameAsDomain: dnsConfig.CNameAsDomain,
|
CnameAsDomain: dnsConfig.CNameAsDomain,
|
||||||
DefaultRoute: defaultRoute,
|
IncludingLnNodes: dnsConfig.IncludingLnNodes,
|
||||||
|
DefaultRoute: defaultRoute,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -610,7 +612,7 @@ func (this *NodeClusterService) UpdateNodeClusterDNS(ctx context.Context, req *p
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedNodeClusterDAO.UpdateClusterDNS(tx, req.NodeClusterId, req.DnsName, req.DnsDomainId, req.NodesAutoSync, req.ServersAutoSync, req.CnameRecords, req.Ttl, req.CnameAsDomain)
|
err = models.SharedNodeClusterDAO.UpdateClusterDNS(tx, req.NodeClusterId, req.DnsName, req.DnsDomainId, req.NodesAutoSync, req.ServersAutoSync, req.CnameRecords, req.Ttl, req.CnameAsDomain, req.IncludingLnNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1184,7 +1186,7 @@ func (this *NodeClusterService) UpdateNodeClusterUAMPolicy(ctx context.Context,
|
|||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindNodeClusterDDoSProtection 获取集群的DDOS设置
|
// FindNodeClusterDDoSProtection 获取集群的DDoS设置
|
||||||
func (this *NodeClusterService) FindNodeClusterDDoSProtection(ctx context.Context, req *pb.FindNodeClusterDDoSProtectionRequest) (*pb.FindNodeClusterDDoSProtectionResponse, error) {
|
func (this *NodeClusterService) FindNodeClusterDDoSProtection(ctx context.Context, req *pb.FindNodeClusterDDoSProtectionRequest) (*pb.FindNodeClusterDDoSProtectionResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, err := this.ValidateAdmin(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1211,7 +1213,7 @@ func (this *NodeClusterService) FindNodeClusterDDoSProtection(ctx context.Contex
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNodeClusterDDoSProtection 修改集群的DDOS设置
|
// UpdateNodeClusterDDoSProtection 修改集群的DDoS设置
|
||||||
func (this *NodeClusterService) UpdateNodeClusterDDoSProtection(ctx context.Context, req *pb.UpdateNodeClusterDDoSProtectionRequest) (*pb.RPCSuccess, error) {
|
func (this *NodeClusterService) UpdateNodeClusterDDoSProtection(ctx context.Context, req *pb.UpdateNodeClusterDDoSProtectionRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, err := this.ValidateAdmin(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -148,10 +148,20 @@ func (this *NodeLogService) UpdateNodeLogsRead(ctx context.Context, req *pb.Upda
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
err = models.SharedNodeLogDAO.UpdateNodeLogsRead(tx, req.NodeLogIds)
|
if len(req.NodeLogIds) > 0 {
|
||||||
if err != nil {
|
err = models.SharedNodeLogDAO.UpdateNodeLogIdsRead(tx, req.NodeLogIds)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if req.NodeId > 0 && len(req.Role) > 0 {
|
||||||
|
err = models.SharedNodeLogDAO.UpdateNodeLogsRead(tx, req.Role, req.NodeId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ func (this *NodeService) NodeStream(server pb.NodeService_NodeStreamServer) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if inactiveNotifiedAt > 0 {
|
if inactiveNotifiedAt > 0 {
|
||||||
|
// 设置为活跃
|
||||||
err = models.SharedNodeDAO.UpdateNodeActive(tx, nodeId, true)
|
err = models.SharedNodeDAO.UpdateNodeActive(tx, nodeId, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -144,6 +145,12 @@ func (this *NodeService) NodeStream(server pb.NodeService_NodeStreamServer) erro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 设置为活跃
|
||||||
|
err = models.SharedNodeDAO.UpdateNodeActive(tx, nodeId, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ func (this *RegionProvinceService) FindAllRegionProvincesWithRegionCountryId(ctx
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := []*pb.RegionProvince{}
|
var result = []*pb.RegionProvince{}
|
||||||
for _, province := range provinces {
|
for _, province := range provinces {
|
||||||
result = append(result, &pb.RegionProvince{
|
result = append(result, &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.Id),
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import (
|
|||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerService struct {
|
type ServerService struct {
|
||||||
@@ -643,8 +645,8 @@ func (this *ServerService) UpdateServerDNS(ctx context.Context, req *pb.UpdateSe
|
|||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegenerateServerCNAME 重新生成CNAME
|
// RegenerateServerDNSName 重新生成CNAME
|
||||||
func (this *ServerService) RegenerateServerCNAME(ctx context.Context, req *pb.RegenerateServerCNAMERequest) (*pb.RPCSuccess, error) {
|
func (this *ServerService) RegenerateServerDNSName(ctx context.Context, req *pb.RegenerateServerDNSNameRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, err := this.ValidateAdmin(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -658,6 +660,81 @@ func (this *ServerService) RegenerateServerCNAME(ctx context.Context, req *pb.Re
|
|||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateServerDNSName 修改服务的CNAME
|
||||||
|
func (this *ServerService) UpdateServerDNSName(ctx context.Context, req *pb.UpdateServerDNSNameRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
var dnsName = req.DnsName
|
||||||
|
|
||||||
|
if req.ServerId <= 0 {
|
||||||
|
return nil, errors.New("invalid 'serverId'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(dnsName) == 0 {
|
||||||
|
return nil, errors.New("'dnsName' must not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理格式
|
||||||
|
dnsName = strings.ToLower(dnsName)
|
||||||
|
const maxLen = 30
|
||||||
|
if len(dnsName) > maxLen {
|
||||||
|
return nil, errors.New("'dnsName' too long than " + types.String(maxLen))
|
||||||
|
}
|
||||||
|
if !regexp.MustCompile(`^[a-z0-9]{1,` + types.String(maxLen) + `}$`).MatchString(dnsName) {
|
||||||
|
return nil, errors.New("invalid 'dnsName': contains invalid character(s)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否被使用
|
||||||
|
clusterId, err := models.SharedServerDAO.FindServerClusterId(tx, req.ServerId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if clusterId <= 0 {
|
||||||
|
return nil, errors.New("the server is not belong to any cluster")
|
||||||
|
}
|
||||||
|
|
||||||
|
serverId, err := models.SharedServerDAO.FindServerIdWithDNSName(tx, clusterId, dnsName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if serverId > 0 && serverId != req.ServerId {
|
||||||
|
return nil, errors.New("the 'dnsName': " + dnsName + " has already been used")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedServerDAO.UpdateServerDNSName(tx, req.ServerId, dnsName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindServerIdWithDNSName 使用CNAME查找服务
|
||||||
|
func (this *ServerService) FindServerIdWithDNSName(ctx context.Context, req *pb.FindServerIdWithDNSNameRequest) (*pb.FindServerIdWithDNSNameResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.DnsName) == 0 {
|
||||||
|
return nil, errors.New("'dnsName' must not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
serverId, err := models.SharedServerDAO.FindServerIdWithDNSName(tx, req.NodeClusterId, req.DnsName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindServerIdWithDNSNameResponse{
|
||||||
|
ServerId: serverId,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CountAllEnabledServersMatch 计算服务数量
|
// CountAllEnabledServersMatch 计算服务数量
|
||||||
func (this *ServerService) CountAllEnabledServersMatch(ctx context.Context, req *pb.CountAllEnabledServersMatchRequest) (*pb.RPCCountResponse, error) {
|
func (this *ServerService) CountAllEnabledServersMatch(ctx context.Context, req *pb.CountAllEnabledServersMatchRequest) (*pb.RPCCountResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
@@ -705,7 +782,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := []*pb.Server{}
|
var result = []*pb.Server{}
|
||||||
for _, server := range servers {
|
for _, server := range servers {
|
||||||
clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(server.ClusterId))
|
clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(server.ClusterId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -713,9 +790,9 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 分组信息
|
// 分组信息
|
||||||
pbGroups := []*pb.ServerGroup{}
|
var pbGroups = []*pb.ServerGroup{}
|
||||||
if models.IsNotNull(server.GroupIds) {
|
if models.IsNotNull(server.GroupIds) {
|
||||||
groupIds := []int64{}
|
var groupIds = []int64{}
|
||||||
err = json.Unmarshal(server.GroupIds, &groupIds)
|
err = json.Unmarshal(server.GroupIds, &groupIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -750,7 +827,7 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 审核结果
|
// 审核结果
|
||||||
auditingResult := &pb.ServerNameAuditingResult{}
|
var auditingResult = &pb.ServerNameAuditingResult{}
|
||||||
if len(server.AuditingResult) > 0 {
|
if len(server.AuditingResult) > 0 {
|
||||||
err = json.Unmarshal(server.AuditingResult, auditingResult)
|
err = json.Unmarshal(server.AuditingResult, auditingResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -770,27 +847,6 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前统计
|
|
||||||
dailyStat, err := models.SharedServerDailyStatDAO.SumCurrentDailyStat(tx, int64(server.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var pbDailyStat *pb.ServerDailyStat
|
|
||||||
if dailyStat != nil {
|
|
||||||
pbDailyStat = &pb.ServerDailyStat{
|
|
||||||
Bytes: int64(dailyStat.Bytes),
|
|
||||||
CachedBytes: int64(dailyStat.CachedBytes),
|
|
||||||
AttackBytes: int64(dailyStat.AttackBytes),
|
|
||||||
CountRequests: int64(dailyStat.CountRequests),
|
|
||||||
CountCachedRequests: int64(dailyStat.CountCachedRequests),
|
|
||||||
CountAttackRequests: int64(dailyStat.CountAttackRequests),
|
|
||||||
Day: dailyStat.Day,
|
|
||||||
Hour: dailyStat.Hour,
|
|
||||||
TimeFrom: dailyStat.TimeFrom,
|
|
||||||
TimeTo: dailyStat.TimeTo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = append(result, &pb.Server{
|
result = append(result, &pb.Server{
|
||||||
Id: int64(server.Id),
|
Id: int64(server.Id),
|
||||||
IsOn: server.IsOn,
|
IsOn: server.IsOn,
|
||||||
@@ -818,9 +874,10 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
Id: int64(server.ClusterId),
|
Id: int64(server.ClusterId),
|
||||||
Name: clusterName,
|
Name: clusterName,
|
||||||
},
|
},
|
||||||
ServerGroups: pbGroups,
|
ServerGroups: pbGroups,
|
||||||
User: pbUser,
|
User: pbUser,
|
||||||
LatestServerDailyStat: pbDailyStat,
|
BandwidthTime: server.BandwidthTime,
|
||||||
|
BandwidthBytes: int64(server.BandwidthBytes),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,19 +29,36 @@ func init() {
|
|||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
func() {
|
func() {
|
||||||
var tx *dbs.Tx
|
|
||||||
|
|
||||||
serverBandwidthStatsLocker.Lock()
|
serverBandwidthStatsLocker.Lock()
|
||||||
var m = serverBandwidthStatsMap
|
var m = serverBandwidthStatsMap
|
||||||
serverBandwidthStatsMap = map[string]*pb.ServerBandwidthStat{}
|
serverBandwidthStatsMap = map[string]*pb.ServerBandwidthStat{}
|
||||||
serverBandwidthStatsLocker.Unlock()
|
serverBandwidthStatsLocker.Unlock()
|
||||||
|
|
||||||
|
tx, err := models.SharedServerBandwidthStatDAO.Instance.Begin()
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("ServerBandwidthStatService", "begin transaction failed: "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
_ = tx.Commit()
|
||||||
|
}()
|
||||||
|
|
||||||
for _, stat := range m {
|
for _, stat := range m {
|
||||||
err := models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.Day, stat.TimeAt, stat.Bytes)
|
// 更新服务的带宽峰值
|
||||||
if err != nil {
|
if stat.ServerId > 0 {
|
||||||
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
|
err := models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.Day, stat.TimeAt, stat.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedServerDAO.UpdateServerBandwidth(tx, stat.ServerId, stat.Day+stat.TimeAt, stat.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("ServerBandwidthStatService", "update server bandwidth failed: "+err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新服务的带宽峰值
|
||||||
if stat.UserId > 0 {
|
if stat.UserId > 0 {
|
||||||
err = models.SharedUserBandwidthStatDAO.UpdateUserBandwidth(tx, stat.UserId, stat.Day, stat.TimeAt, stat.Bytes)
|
err = models.SharedUserBandwidthStatDAO.UpdateUserBandwidth(tx, stat.UserId, stat.Day, stat.TimeAt, stat.Bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -144,3 +161,39 @@ func (this *ServerBandwidthStatService) FindServerBandwidthStats(ctx context.Con
|
|||||||
ServerBandwidthStats: pbStats,
|
ServerBandwidthStats: pbStats,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindHourlyServerBandwidthStats 获取最近N小时峰值带宽
|
||||||
|
func (this *ServerBandwidthStatService) FindHourlyServerBandwidthStats(ctx context.Context, req *pb.FindHourlyServerBandwidthStatsRequest) (*pb.FindHourlyServerBandwidthStatsResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
stats, err := models.SharedServerBandwidthStatDAO.FindHourlyBandwidthStats(tx, req.ServerId, req.Hours)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindHourlyServerBandwidthStatsResponse{
|
||||||
|
Stats: stats,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindDailyServerBandwidthStats 获取最近N天峰值带宽
|
||||||
|
func (this *ServerBandwidthStatService) FindDailyServerBandwidthStats(ctx context.Context, req *pb.FindDailyServerBandwidthStatsRequest) (*pb.FindDailyServerBandwidthStatsResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
stats, err := models.SharedServerBandwidthStatDAO.FindDailyBandwidthStats(tx, req.ServerId, req.Days)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindDailyServerBandwidthStatsResponse{
|
||||||
|
Stats: stats,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func (this *ServerRegionCityMonthlyStatService) FindTopServerRegionCityMonthlySt
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pbStats := []*pb.FindTopServerRegionCityMonthlyStatsResponse_Stat{}
|
var pbStats = []*pb.FindTopServerRegionCityMonthlyStatsResponse_Stat{}
|
||||||
for _, stat := range statList {
|
for _, stat := range statList {
|
||||||
pbStat := &pb.FindTopServerRegionCityMonthlyStatsResponse_Stat{
|
pbStat := &pb.FindTopServerRegionCityMonthlyStatsResponse_Stat{
|
||||||
Count: int64(stat.Count),
|
Count: int64(stat.Count),
|
||||||
@@ -63,15 +63,15 @@ func (this *ServerRegionCityMonthlyStatService) FindTopServerRegionCityMonthlySt
|
|||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.Id),
|
||||||
Name: country.Name,
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionProvince = &pb.RegionProvince{
|
pbStat.RegionProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.Id),
|
||||||
Name: province.Name,
|
Name: province.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionCity = &pb.RegionCity{
|
pbStat.RegionCity = &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.Id),
|
||||||
Name: city.Name,
|
Name: city.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func (this *ServerRegionCountryMonthlyStatService) FindTopServerRegionCountryMon
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pbStats := []*pb.FindTopServerRegionCountryMonthlyStatsResponse_Stat{}
|
var pbStats = []*pb.FindTopServerRegionCountryMonthlyStatsResponse_Stat{}
|
||||||
for _, stat := range statList {
|
for _, stat := range statList {
|
||||||
pbStat := &pb.FindTopServerRegionCountryMonthlyStatsResponse_Stat{
|
pbStat := &pb.FindTopServerRegionCountryMonthlyStatsResponse_Stat{
|
||||||
Count: int64(stat.Count),
|
Count: int64(stat.Count),
|
||||||
@@ -47,7 +47,7 @@ func (this *ServerRegionCountryMonthlyStatService) FindTopServerRegionCountryMon
|
|||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.Id),
|
||||||
Name: country.Name,
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
|
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func (this *ServerRegionProviderMonthlyStatService) FindTopServerRegionProviderM
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pbStats := []*pb.FindTopServerRegionProviderMonthlyStatsResponse_Stat{}
|
var pbStats = []*pb.FindTopServerRegionProviderMonthlyStatsResponse_Stat{}
|
||||||
for _, stat := range statList {
|
for _, stat := range statList {
|
||||||
pbStat := &pb.FindTopServerRegionProviderMonthlyStatsResponse_Stat{
|
pbStat := &pb.FindTopServerRegionProviderMonthlyStatsResponse_Stat{
|
||||||
Count: int64(stat.Count),
|
Count: int64(stat.Count),
|
||||||
@@ -46,7 +46,7 @@ func (this *ServerRegionProviderMonthlyStatService) FindTopServerRegionProviderM
|
|||||||
}
|
}
|
||||||
pbStat.RegionProvider = &pb.RegionProvider{
|
pbStat.RegionProvider = &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.Id),
|
||||||
Name: provider.Name,
|
Name: provider.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func (this *ServerRegionProvinceMonthlyStatService) FindTopServerRegionProvinceM
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pbStats := []*pb.FindTopServerRegionProvinceMonthlyStatsResponse_Stat{}
|
var pbStats = []*pb.FindTopServerRegionProvinceMonthlyStatsResponse_Stat{}
|
||||||
for _, stat := range statList {
|
for _, stat := range statList {
|
||||||
pbStat := &pb.FindTopServerRegionProvinceMonthlyStatsResponse_Stat{
|
pbStat := &pb.FindTopServerRegionProvinceMonthlyStatsResponse_Stat{
|
||||||
Count: int64(stat.Count),
|
Count: int64(stat.Count),
|
||||||
@@ -53,11 +53,11 @@ func (this *ServerRegionProvinceMonthlyStatService) FindTopServerRegionProvinceM
|
|||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.Id),
|
||||||
Name: country.Name,
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionProvince = &pb.RegionProvince{
|
pbStat.RegionProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.Id),
|
||||||
Name: province.Name,
|
Name: province.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -424,10 +424,6 @@ func (this *ServerStatBoardService) ComposeServerStatBoard(ctx context.Context,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if bytes == 0 {
|
|
||||||
// 尝试从缓存中读取
|
|
||||||
bytes = ServerBandwidthGetCacheBytes(req.ServerId, day, minute)
|
|
||||||
}
|
|
||||||
|
|
||||||
if bytes > 0 {
|
if bytes > 0 {
|
||||||
result.MinutelyPeekBandwidthBytes = bytes
|
result.MinutelyPeekBandwidthBytes = bytes
|
||||||
|
|||||||
@@ -557,6 +557,22 @@ func (this *UserService) UpdateUserFeatures(ctx context.Context, req *pb.UpdateU
|
|||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateAllUsersFeatures 设置所有用户能使用的功能
|
||||||
|
func (this *UserService) UpdateAllUsersFeatures(ctx context.Context, req *pb.UpdateAllUsersFeaturesRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedUserDAO.UpdateUsersFeatures(tx, req.FeatureCodes, req.Overwrite)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
// FindUserFeatures 获取用户所有的功能列表
|
// FindUserFeatures 获取用户所有的功能列表
|
||||||
func (this *UserService) FindUserFeatures(ctx context.Context, req *pb.FindUserFeaturesRequest) (*pb.FindUserFeaturesResponse, error) {
|
func (this *UserService) FindUserFeatures(ctx context.Context, req *pb.FindUserFeaturesRequest) (*pb.FindUserFeaturesResponse, error) {
|
||||||
_, userId, err := this.ValidateAdminAndUser(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -355,12 +355,12 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 当前的节点记录
|
// 当前的节点记录
|
||||||
newRecordKeys := []string{}
|
var newRecordKeys = []string{}
|
||||||
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true)
|
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true, dnsConfig != nil && dnsConfig.IncludingLnNodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
isChanged := false
|
var isChanged = false
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
routes, err := node.DNSRouteCodesForDomainId(domainId)
|
routes, err := node.DNSRouteCodesForDomainId(domainId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -379,7 +379,7 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, ipAddress := range ipAddresses {
|
for _, ipAddress := range ipAddresses {
|
||||||
ip := ipAddress.DNSIP()
|
var ip = ipAddress.DNSIP()
|
||||||
if len(ip) == 0 || !ipAddress.CanAccess || !ipAddress.IsUp || !ipAddress.IsOn {
|
if len(ip) == 0 || !ipAddress.CanAccess || !ipAddress.IsUp || !ipAddress.IsOn {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -387,14 +387,14 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
key := route + "@" + ip
|
var key = route + "@" + ip
|
||||||
_, ok := oldRecordsMap[key]
|
_, ok := oldRecordsMap[key]
|
||||||
if ok {
|
if ok {
|
||||||
newRecordKeys = append(newRecordKeys, key)
|
newRecordKeys = append(newRecordKeys, key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
recordType := dnstypes.RecordTypeA
|
var recordType = dnstypes.RecordTypeA
|
||||||
if utils.IsIPv6(ip) {
|
if utils.IsIPv6(ip) {
|
||||||
recordType = dnstypes.RecordTypeAAAA
|
recordType = dnstypes.RecordTypeAAAA
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
package tasks
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
dbs.OnReadyDone(func() {
|
|
||||||
goman.New(func() {
|
|
||||||
NewNSNodeMonitorTask(1 * time.Minute).Start()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// NSNodeMonitorTask 边缘节点监控任务
|
|
||||||
type NSNodeMonitorTask struct {
|
|
||||||
BaseTask
|
|
||||||
|
|
||||||
ticker *time.Ticker
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNSNodeMonitorTask(duration time.Duration) *NSNodeMonitorTask {
|
|
||||||
return &NSNodeMonitorTask{
|
|
||||||
ticker: time.NewTicker(duration),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *NSNodeMonitorTask) Start() {
|
|
||||||
for range this.ticker.C {
|
|
||||||
err := this.Loop()
|
|
||||||
if err != nil {
|
|
||||||
this.logErr("NS_NODE_MONITOR", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *NSNodeMonitorTask) Loop() error {
|
|
||||||
// 检查是否为主节点
|
|
||||||
if !models.SharedAPINodeDAO.CheckAPINodeIsPrimaryWithoutErr() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
clusters, err := models.SharedNSClusterDAO.FindAllEnabledClusters(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, cluster := range clusters {
|
|
||||||
err := this.monitorCluster(cluster)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *NSNodeMonitorTask) monitorCluster(cluster *models.NSCluster) error {
|
|
||||||
clusterId := int64(cluster.Id)
|
|
||||||
|
|
||||||
// 检查离线节点
|
|
||||||
inactiveNodes, err := models.SharedNSNodeDAO.FindAllNotifyingInactiveNodesWithClusterId(nil, clusterId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, node := range inactiveNodes {
|
|
||||||
subject := "DNS节点\"" + node.Name + "\"已处于离线状态"
|
|
||||||
msg := "DNS节点\"" + node.Name + "\"已处于离线状态"
|
|
||||||
err = models.SharedMessageDAO.CreateNodeMessage(nil, nodeconfigs.NodeRoleDNS, clusterId, int64(node.Id), models.MessageTypeNSNodeInactive, models.LevelError, subject, msg, nil, false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改在线状态
|
|
||||||
err = models.SharedNSNodeDAO.UpdateNodeStatusIsNotified(nil, int64(node.Id))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO 检查恢复连接
|
|
||||||
|
|
||||||
// 检查CPU、内存、磁盘不足节点,而且离线的节点不再重复提示
|
|
||||||
// TODO 需要实现
|
|
||||||
|
|
||||||
// TODO 检查53/tcp、53/udp是否能够访问
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -102,8 +102,8 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
|||||||
}
|
}
|
||||||
for _, cert := range certs {
|
for _, cert := range certs {
|
||||||
// 发送消息
|
// 发送消息
|
||||||
subject := "SSL证书\"" + cert.Name + "\"在" + strconv.Itoa(days) + "天后将到期,"
|
var subject = "SSL证书\"" + cert.Name + "\"在" + strconv.Itoa(days) + "天后将到期,"
|
||||||
msg := "SSL证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")在" + strconv.Itoa(days) + "天后将到期,"
|
var msg = "SSL证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")在" + strconv.Itoa(days) + "天后将到期,"
|
||||||
|
|
||||||
// 是否有自动更新任务
|
// 是否有自动更新任务
|
||||||
if cert.AcmeTaskId > 0 {
|
if cert.AcmeTaskId > 0 {
|
||||||
@@ -116,7 +116,7 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
|||||||
isOk, errMsg, _ := acme.SharedACMETaskDAO.RunTask(nil, int64(cert.AcmeTaskId))
|
isOk, errMsg, _ := acme.SharedACMETaskDAO.RunTask(nil, int64(cert.AcmeTaskId))
|
||||||
if isOk {
|
if isOk {
|
||||||
// 发送成功通知
|
// 发送成功通知
|
||||||
subject := "系统已成功为你自动更新了证书\"" + cert.Name + "\""
|
subject = "系统已成功为你自动更新了证书\"" + cert.Name + "\""
|
||||||
msg = "系统已成功为你自动更新了证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")。"
|
msg = "系统已成功为你自动更新了证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")。"
|
||||||
err = models.SharedMessageDAO.CreateMessage(nil, int64(cert.AdminId), int64(cert.UserId), models.MessageTypeSSLCertACMETaskSuccess, models.MessageLevelSuccess, subject, msg, maps.Map{
|
err = models.SharedMessageDAO.CreateMessage(nil, int64(cert.AdminId), int64(cert.UserId), models.MessageTypeSSLCertACMETaskSuccess, models.MessageLevelSuccess, subject, msg, maps.Map{
|
||||||
"certId": cert.Id,
|
"certId": cert.Id,
|
||||||
@@ -130,7 +130,7 @@ func (this *SSLCertExpireCheckExecutor) Loop() error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 发送失败通知
|
// 发送失败通知
|
||||||
subject := "系统在尝试自动更新证书\"" + cert.Name + "\"时发生错误"
|
subject = "系统在尝试自动更新证书\"" + cert.Name + "\"时发生错误"
|
||||||
msg = "系统在尝试自动更新证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")时发生错误:" + errMsg + "。请检查系统设置并修复错误。"
|
msg = "系统在尝试自动更新证书\"" + cert.Name + "\"(" + string(cert.DnsNames) + ")时发生错误:" + errMsg + "。请检查系统设置并修复错误。"
|
||||||
err = models.SharedMessageDAO.CreateMessage(nil, int64(cert.AdminId), int64(cert.UserId), models.MessageTypeSSLCertACMETaskFailed, models.MessageLevelError, subject, msg, maps.Map{
|
err = models.SharedMessageDAO.CreateMessage(nil, int64(cert.AdminId), int64(cert.UserId), models.MessageTypeSSLCertACMETaskFailed, models.MessageLevelError, subject, msg, maps.Map{
|
||||||
"certId": cert.Id,
|
"certId": cert.Id,
|
||||||
|
|||||||
@@ -62,3 +62,23 @@ func Similar(s1 string, s2 string) float32 {
|
|||||||
|
|
||||||
return (float32(count)/float32(l1) + float32(count)/float32(l2)) / 2
|
return (float32(count)/float32(l1) + float32(count)/float32(l2)) / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LimitString 限制字符串长度
|
||||||
|
func LimitString(s string, maxLength int) string {
|
||||||
|
if len(s) <= maxLength {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
if maxLength <= 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var runes = []rune(s)
|
||||||
|
var rs = len(runes)
|
||||||
|
for i := 0; i < rs; i++ {
|
||||||
|
if len(string(runes[:i+1])) > maxLength {
|
||||||
|
return string(runes[:i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,3 +28,15 @@ func TestSimilar(t *testing.T) {
|
|||||||
t.Log(utils.Similar("efgj", "hijk"))
|
t.Log(utils.Similar("efgj", "hijk"))
|
||||||
t.Log(utils.Similar("efgj", "klmn"))
|
t.Log(utils.Similar("efgj", "klmn"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLimitString(t *testing.T) {
|
||||||
|
var a = assert.NewAssertion(t)
|
||||||
|
a.IsTrue(utils.LimitString("", 4) == "")
|
||||||
|
a.IsTrue(utils.LimitString("abcd", 0) == "")
|
||||||
|
a.IsTrue(utils.LimitString("abcd", 5) == "abcd")
|
||||||
|
a.IsTrue(utils.LimitString("abcd", 4) == "abcd")
|
||||||
|
a.IsTrue(utils.LimitString("abcd", 3) == "abc")
|
||||||
|
a.IsTrue(utils.LimitString("abcd", 1) == "a")
|
||||||
|
a.IsTrue(utils.LimitString("中文测试", 1) == "")
|
||||||
|
a.IsTrue(utils.LimitString("中文测试", 3) == "中")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user