Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84483dce61 | ||
|
|
a4eb7a47f3 | ||
|
|
20c84d7fe5 | ||
|
|
9d5acd2b36 | ||
|
|
7508f6b92b | ||
|
|
379030fe71 | ||
|
|
10027eea20 | ||
|
|
69f25a176b | ||
|
|
ac19f06b6c | ||
|
|
87a81f59c7 | ||
|
|
7389e5e54b | ||
|
|
e6792b8188 | ||
|
|
a037546cfa | ||
|
|
8efaacf1ef | ||
|
|
a38dd1cef8 | ||
|
|
77521112d0 | ||
|
|
4f9a5d238c | ||
|
|
d5fb39ed50 | ||
|
|
58a84083ae | ||
|
|
9f564a4739 | ||
|
|
c20accbf58 | ||
|
|
3f21b3148e | ||
|
|
74e909a501 | ||
|
|
4150ee1b47 | ||
|
|
df04de2151 | ||
|
|
4dc5d9aa7e | ||
|
|
0ef7e6ccd8 | ||
|
|
ed2b831e5a | ||
|
|
5d392ecd43 | ||
|
|
ea147d7506 | ||
|
|
b45136c2c8 | ||
|
|
530e1513ec | ||
|
|
6c60677b72 | ||
|
|
a1bec5e578 | ||
|
|
9dece058d9 | ||
|
|
89df6ae6bf | ||
|
|
85b6e6428c | ||
|
|
0df204a1df | ||
|
|
ecef94b700 | ||
|
|
a493bbb280 | ||
|
|
eee902abec | ||
|
|
2aceb4fb4d | ||
|
|
c1bbcc8dab | ||
|
|
262f8a5594 | ||
|
|
a85b49a377 | ||
|
|
75e353db0e | ||
|
|
ccbb14836e | ||
|
|
7fbc61aa21 | ||
|
|
8b804cb500 | ||
|
|
3ddb95731a | ||
|
|
beeb46ab7f | ||
|
|
a65255e4e5 | ||
|
|
b7768ea0c0 |
@@ -12,5 +12,5 @@ dbs:
|
|||||||
|
|
||||||
|
|
||||||
fields:
|
fields:
|
||||||
bool: [ "uamIsOn", "followPort", "requestHostExcludingPort", "autoRemoteStart", "autoInstallNftables", "enableIPLists", "detectAgents", "checkingPorts", "enableRecordHealthCheck", "offlineIsNotified" ]
|
bool: [ "uamIsOn", "followPort", "requestHostExcludingPort", "autoRemoteStart", "autoInstallNftables", "enableIPLists", "detectAgents", "checkingPorts", "enableRecordHealthCheck", "offlineIsNotified", "http2Enabled", "http3Enabled" ]
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
unzip := helpers.NewUnzip(zipPath, targetPath)
|
var unzip = helpers.NewUnzip(zipPath, targetPath)
|
||||||
err := unzip.Run()
|
err := unzip.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stderr("ERROR: " + err.Error())
|
stderr("ERROR: " + err.Error())
|
||||||
|
|||||||
13
go.mod
13
go.mod
@@ -10,25 +10,26 @@ require (
|
|||||||
github.com/andybalholm/brotli v1.0.4
|
github.com/andybalholm/brotli v1.0.4
|
||||||
github.com/cespare/xxhash v1.1.0
|
github.com/cespare/xxhash v1.1.0
|
||||||
github.com/cespare/xxhash/v2 v2.1.1
|
github.com/cespare/xxhash/v2 v2.1.1
|
||||||
github.com/go-acme/lego/v4 v4.9.0
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
|
github.com/go-acme/lego/v4 v4.10.2
|
||||||
github.com/go-sql-driver/mysql v1.7.0
|
github.com/go-sql-driver/mysql v1.7.0
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
||||||
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470
|
github.com/iwind/TeaGo v0.0.0-20230704135818-4a5646ab1f5b
|
||||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62
|
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62
|
||||||
github.com/miekg/dns v1.1.50
|
github.com/miekg/dns v1.1.50
|
||||||
github.com/mozillazg/go-pinyin v0.18.0
|
github.com/mozillazg/go-pinyin v0.18.0
|
||||||
github.com/pkg/sftp v1.12.0
|
github.com/pkg/sftp v1.12.0
|
||||||
github.com/shirou/gopsutil/v3 v3.22.2
|
github.com/shirou/gopsutil/v3 v3.22.2
|
||||||
github.com/smartwalle/alipay/v3 v3.1.7
|
github.com/smartwalle/alipay/v3 v3.1.7
|
||||||
golang.org/x/crypto v0.1.0
|
golang.org/x/crypto v0.5.0
|
||||||
golang.org/x/net v0.8.0
|
golang.org/x/net v0.8.0
|
||||||
golang.org/x/sys v0.6.0
|
golang.org/x/sys v0.8.0
|
||||||
google.golang.org/grpc v1.45.0
|
google.golang.org/grpc v1.45.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
@@ -40,6 +41,8 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||||
github.com/smartwalle/crypto4go v1.0.2 // indirect
|
github.com/smartwalle/crypto4go v1.0.2 // indirect
|
||||||
|
github.com/tdewolff/minify/v2 v2.12.7 // indirect
|
||||||
|
github.com/tdewolff/parse/v2 v2.6.6 // indirect
|
||||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
github.com/tklauser/go-sysconf v0.3.9 // indirect
|
||||||
github.com/tklauser/numcpus v0.3.0 // indirect
|
github.com/tklauser/numcpus v0.3.0 // indirect
|
||||||
|
|||||||
32
go.sum
32
go.sum
@@ -12,13 +12,14 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY
|
|||||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
@@ -30,6 +31,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
|
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
@@ -38,6 +41,8 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
|
|||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
@@ -79,8 +84,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
||||||
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470 h1:TuRxvKRv9PxKVijWOkUnZm5TeanQqWGUJyPx9u6cra4=
|
github.com/iwind/TeaGo v0.0.0-20230704135818-4a5646ab1f5b h1:yYUaxnc04uzfr7C9HBN52ZZvcQomND+C5aZTpjOUYFI=
|
||||||
github.com/iwind/TeaGo v0.0.0-20230304012706-c1f4a4e27470/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
|
github.com/iwind/TeaGo v0.0.0-20230704135818-4a5646ab1f5b/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
|
||||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 h1:HJH6RDheAY156DnIfJSD/bEvqyXzsZuE2gzs8PuUjoo=
|
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 h1:HJH6RDheAY156DnIfJSD/bEvqyXzsZuE2gzs8PuUjoo=
|
||||||
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
|
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
@@ -96,10 +101,11 @@ github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
|||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||||
|
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@@ -140,12 +146,20 @@ github.com/smartwalle/crypto4go v1.0.2 h1:9DUEOOsPhmp00438L4oBdcL8EZG1zumecft5bW
|
|||||||
github.com/smartwalle/crypto4go v1.0.2/go.mod h1:LQ7vCZIb7BE5+MuMtJBuO8ORkkQ01m4DXDBWPzLbkMY=
|
github.com/smartwalle/crypto4go v1.0.2/go.mod h1:LQ7vCZIb7BE5+MuMtJBuO8ORkkQ01m4DXDBWPzLbkMY=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||||
|
github.com/tdewolff/minify/v2 v2.12.7 h1:pBzz2tAfz5VghOXiQIsSta6srhmTeinQPjRDHWoumCA=
|
||||||
|
github.com/tdewolff/minify/v2 v2.12.7/go.mod h1:ZRKTheiOGyLSK8hOZWWv+YoJAECzDivNgAlVYDHp/Ws=
|
||||||
|
github.com/tdewolff/parse/v2 v2.6.6 h1:Yld+0CrKUJaCV78DL1G2nk3C9lKrxyRTux5aaK/AkDo=
|
||||||
|
github.com/tdewolff/parse/v2 v2.6.6/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
|
||||||
|
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
|
github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0=
|
||||||
|
github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
||||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||||
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
|
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
|
||||||
@@ -162,8 +176,8 @@ golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||||
@@ -222,8 +236,10 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "1.1.0"
|
Version = "1.2.2"
|
||||||
|
|
||||||
ProductName = "Edge API"
|
ProductName = "Edge API"
|
||||||
ProcessName = "edge-api"
|
ProcessName = "edge-api"
|
||||||
@@ -18,7 +18,7 @@ const (
|
|||||||
|
|
||||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||||
|
|
||||||
NodeVersion = "1.1.0"
|
NodeVersion = "1.2.2"
|
||||||
|
|
||||||
// SQLVersion SQL版本号
|
// SQLVersion SQL版本号
|
||||||
SQLVersion = "11"
|
SQLVersion = "11"
|
||||||
|
|||||||
@@ -2,6 +2,22 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
AdminField_Id dbs.FieldName = "id" // ID
|
||||||
|
AdminField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
AdminField_Username dbs.FieldName = "username" // 用户名
|
||||||
|
AdminField_Password dbs.FieldName = "password" // 密码
|
||||||
|
AdminField_Fullname dbs.FieldName = "fullname" // 全名
|
||||||
|
AdminField_IsSuper dbs.FieldName = "isSuper" // 是否为超级管理员
|
||||||
|
AdminField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
AdminField_UpdatedAt dbs.FieldName = "updatedAt" // 修改时间
|
||||||
|
AdminField_State dbs.FieldName = "state" // 状态
|
||||||
|
AdminField_Modules dbs.FieldName = "modules" // 允许的模块
|
||||||
|
AdminField_CanLogin dbs.FieldName = "canLogin" // 是否可以登录
|
||||||
|
AdminField_Theme dbs.FieldName = "theme" // 模板设置
|
||||||
|
AdminField_Lang dbs.FieldName = "lang" // 语言代号
|
||||||
|
)
|
||||||
|
|
||||||
// Admin 管理员
|
// Admin 管理员
|
||||||
type Admin struct {
|
type Admin struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -16,6 +32,7 @@ type Admin struct {
|
|||||||
Modules dbs.JSON `field:"modules"` // 允许的模块
|
Modules dbs.JSON `field:"modules"` // 允许的模块
|
||||||
CanLogin bool `field:"canLogin"` // 是否可以登录
|
CanLogin bool `field:"canLogin"` // 是否可以登录
|
||||||
Theme string `field:"theme"` // 模板设置
|
Theme string `field:"theme"` // 模板设置
|
||||||
|
Lang string `field:"lang"` // 语言代号
|
||||||
}
|
}
|
||||||
|
|
||||||
type AdminOperator struct {
|
type AdminOperator struct {
|
||||||
@@ -31,6 +48,7 @@ type AdminOperator struct {
|
|||||||
Modules any // 允许的模块
|
Modules any // 允许的模块
|
||||||
CanLogin any // 是否可以登录
|
CanLogin any // 是否可以登录
|
||||||
Theme any // 模板设置
|
Theme any // 模板设置
|
||||||
|
Lang any // 语言代号
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAdminOperator() *AdminOperator {
|
func NewAdminOperator() *AdminOperator {
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ func (this *APINodeDAO) UpdateAPINodeStatus(tx *dbs.Tx, apiNodeId int64, statusJ
|
|||||||
func (this *APINodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
func (this *APINodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(APINodeStateEnabled).
|
State(APINodeStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
Where("status IS NOT NULL").
|
Where("status IS NOT NULL").
|
||||||
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
||||||
Param("version", utils.VersionToLong(version)).
|
Param("version", utils.VersionToLong(version)).
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ func (this *AuthorityNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, nodeSta
|
|||||||
func (this *AuthorityNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
func (this *AuthorityNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(AuthorityNodeStateEnabled).
|
State(AuthorityNodeStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
Where("status IS NOT NULL").
|
Where("status IS NOT NULL").
|
||||||
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
||||||
Param("version", utils.VersionToLong(version)).
|
Param("version", utils.VersionToLong(version)).
|
||||||
|
|||||||
@@ -155,6 +155,12 @@ func (this *DNSTaskDAO) DeleteDNSTask(tx *dbs.Tx, taskId int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllDNSTasks 删除所有任务
|
||||||
|
func (this *DNSTaskDAO) DeleteAllDNSTasks(tx *dbs.Tx) error {
|
||||||
|
return this.Query(tx).
|
||||||
|
DeleteQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateDNSTaskError 设置任务错误
|
// UpdateDNSTaskError 设置任务错误
|
||||||
func (this *DNSTaskDAO) UpdateDNSTaskError(tx *dbs.Tx, taskId int64, err string) error {
|
func (this *DNSTaskDAO) UpdateDNSTaskError(tx *dbs.Tx, taskId int64, err string) error {
|
||||||
if taskId <= 0 {
|
if taskId <= 0 {
|
||||||
@@ -195,6 +201,27 @@ func (this *DNSTaskDAO) UpdateDNSTaskDone(tx *dbs.Tx, taskId int64, taskVersion
|
|||||||
return this.Save(tx, op)
|
return this.Save(tx, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateVersion 生成最新的版本号
|
||||||
|
func (this *DNSTaskDAO) GenerateVersion() int64 {
|
||||||
|
return time.Now().UnixNano()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateClusterDNSTasksDone 设置所有集群任务完成
|
||||||
|
func (this *DNSTaskDAO) UpdateClusterDNSTasksDone(tx *dbs.Tx, clusterId int64, maxVersion int64) error {
|
||||||
|
if clusterId <= 0 || maxVersion <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Query(tx).
|
||||||
|
Attr("clusterId", clusterId).
|
||||||
|
Attr("isOk", false).
|
||||||
|
Lte("version", maxVersion).
|
||||||
|
Set("isDone", true).
|
||||||
|
Set("isOk", true).
|
||||||
|
Set("error", "").
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteDNSTasksWithClusterId 删除集群相关任务
|
// DeleteDNSTasksWithClusterId 删除集群相关任务
|
||||||
func (this *DNSTaskDAO) DeleteDNSTasksWithClusterId(tx *dbs.Tx, clusterId int64) error {
|
func (this *DNSTaskDAO) DeleteDNSTasksWithClusterId(tx *dbs.Tx, clusterId int64) error {
|
||||||
if clusterId <= 0 {
|
if clusterId <= 0 {
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
package dns
|
package dns_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
||||||
_ "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"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDNSTaskDAO_CreateDNSTask(t *testing.T) {
|
func TestDNSTaskDAO_CreateDNSTask(t *testing.T) {
|
||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
err := SharedDNSTaskDAO.CreateDNSTask(nil, 1, 2, 3, 0, "cdn", "taskType")
|
err := dns.SharedDNSTaskDAO.CreateDNSTask(nil, 1, 2, 3, 0, "cdn", "taskType")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDNSTaskDAO_UpdateClusterDNSTasksDone(t *testing.T) {
|
||||||
|
var dao = dns.NewDNSTaskDAO()
|
||||||
|
var tx *dbs.Tx
|
||||||
|
err := dao.UpdateClusterDNSTasksDone(tx, 46, time.Now().UnixNano())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ func (this *HTTPCachePolicyDAO) FindAllEnabledCachePolicies(tx *dbs.Tx) (result
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateCachePolicy 创建缓存策略
|
// CreateCachePolicy 创建缓存策略
|
||||||
func (this *HTTPCachePolicyDAO) CreateCachePolicy(tx *dbs.Tx, isOn bool, name string, description string, capacityJSON []byte, maxKeys int64, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) (int64, error) {
|
func (this *HTTPCachePolicyDAO) CreateCachePolicy(tx *dbs.Tx, isOn bool, name string, description string, capacityJSON []byte, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) (int64, error) {
|
||||||
var op = NewHTTPCachePolicyOperator()
|
var op = NewHTTPCachePolicyOperator()
|
||||||
op.State = HTTPCachePolicyStateEnabled
|
op.State = HTTPCachePolicyStateEnabled
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
@@ -105,7 +105,6 @@ func (this *HTTPCachePolicyDAO) CreateCachePolicy(tx *dbs.Tx, isOn bool, name st
|
|||||||
if len(capacityJSON) > 0 {
|
if len(capacityJSON) > 0 {
|
||||||
op.Capacity = capacityJSON
|
op.Capacity = capacityJSON
|
||||||
}
|
}
|
||||||
op.MaxKeys = maxKeys
|
|
||||||
if len(maxSizeJSON) > 0 {
|
if len(maxSizeJSON) > 0 {
|
||||||
op.MaxSize = maxSizeJSON
|
op.MaxSize = maxSizeJSON
|
||||||
}
|
}
|
||||||
@@ -184,7 +183,7 @@ func (this *HTTPCachePolicyDAO) CreateDefaultCachePolicy(tx *dbs.Tx, name string
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
policyId, err := this.CreateCachePolicy(tx, true, "\""+name+"\"缓存策略", "默认创建的缓存策略", capacityJSON, 0, maxSizeJSON, serverconfigs.CachePolicyStorageFile, storageOptionsJSON, false)
|
policyId, err := this.CreateCachePolicy(tx, true, "\""+name+"\"缓存策略", "默认创建的缓存策略", capacityJSON, maxSizeJSON, serverconfigs.CachePolicyStorageFile, storageOptionsJSON, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -192,7 +191,7 @@ func (this *HTTPCachePolicyDAO) CreateDefaultCachePolicy(tx *dbs.Tx, name string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCachePolicy 修改缓存策略
|
// UpdateCachePolicy 修改缓存策略
|
||||||
func (this *HTTPCachePolicyDAO) UpdateCachePolicy(tx *dbs.Tx, policyId int64, isOn bool, name string, description string, capacityJSON []byte, maxKeys int64, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) error {
|
func (this *HTTPCachePolicyDAO) UpdateCachePolicy(tx *dbs.Tx, policyId int64, isOn bool, name string, description string, capacityJSON []byte, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) error {
|
||||||
if policyId <= 0 {
|
if policyId <= 0 {
|
||||||
return errors.New("invalid policyId")
|
return errors.New("invalid policyId")
|
||||||
}
|
}
|
||||||
@@ -205,7 +204,6 @@ func (this *HTTPCachePolicyDAO) UpdateCachePolicy(tx *dbs.Tx, policyId int64, is
|
|||||||
if len(capacityJSON) > 0 {
|
if len(capacityJSON) > 0 {
|
||||||
op.Capacity = capacityJSON
|
op.Capacity = capacityJSON
|
||||||
}
|
}
|
||||||
op.MaxKeys = maxKeys
|
|
||||||
if len(maxSizeJSON) > 0 {
|
if len(maxSizeJSON) > 0 {
|
||||||
op.MaxSize = maxSizeJSON
|
op.MaxSize = maxSizeJSON
|
||||||
}
|
}
|
||||||
@@ -256,8 +254,6 @@ func (this *HTTPCachePolicyDAO) ComposeCachePolicy(tx *dbs.Tx, policyId int64, c
|
|||||||
config.Capacity = capacityConfig
|
config.Capacity = capacityConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
config.MaxKeys = types.Int64(policy.MaxKeys)
|
|
||||||
|
|
||||||
// max size
|
// max size
|
||||||
if IsNotNull(policy.MaxSize) {
|
if IsNotNull(policy.MaxSize) {
|
||||||
maxSizeConfig := &shared.SizeCapacity{}
|
maxSizeConfig := &shared.SizeCapacity{}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedHTTPCacheTaskDAO.Clean(nil, 30) // 只保留N天
|
err := SharedHTTPCacheTaskDAO.CleanDefaultDays(nil, 30) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("HTTPCacheTaskDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("HTTPCacheTaskDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -228,8 +228,8 @@ func (this *HTTPCacheTaskDAO) CheckUserTask(tx *dbs.Tx, userId int64, taskId int
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理以往的任务
|
// CleanDays 清理N天以前的任务
|
||||||
func (this *HTTPCacheTaskDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *HTTPCacheTaskDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
if days <= 0 {
|
if days <= 0 {
|
||||||
days = 30
|
days = 30
|
||||||
}
|
}
|
||||||
@@ -248,6 +248,23 @@ func (this *HTTPCacheTaskDAO) Clean(tx *dbs.Tx, days int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CleanDefaultDays 清除任务
|
||||||
|
func (this *HTTPCacheTaskDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.HTTPCacheTask.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.HTTPCacheTask.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyChange 发送通知
|
// NotifyChange 发送通知
|
||||||
func (this *HTTPCacheTaskDAO) NotifyChange(tx *dbs.Tx, taskId int64) error {
|
func (this *HTTPCacheTaskDAO) NotifyChange(tx *dbs.Tx, taskId int64) error {
|
||||||
// TODO
|
// TODO
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
func TestHTTPCacheTaskDAO_Clean(t *testing.T) {
|
func TestHTTPCacheTaskDAO_Clean(t *testing.T) {
|
||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
|
|
||||||
err := models.SharedHTTPCacheTaskDAO.Clean(nil, 30)
|
err := models.SharedHTTPCacheTaskDAO.CleanDays(nil, 30)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ func (this *HTTPFirewallPolicyDAO) CreateFirewallPolicy(tx *dbs.Tx, userId int64
|
|||||||
op.Outbound = outboundJSON
|
op.Outbound = outboundJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
if userId <= 0 && serverGroupId <=0 && serverId <= 0 {
|
if userId <= 0 && serverGroupId <= 0 && serverId <= 0 {
|
||||||
// synFlood
|
// synFlood
|
||||||
var synFloodConfig = firewallconfigs.DefaultSYNFloodConfig()
|
var synFloodConfig = firewallconfigs.DefaultSYNFloodConfig()
|
||||||
synFloodJSON, err := json.Marshal(synFloodConfig)
|
synFloodJSON, err := json.Marshal(synFloodConfig)
|
||||||
@@ -611,6 +611,10 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyServerId(tx *dbs.Tx, poli
|
|||||||
|
|
||||||
// FindFirewallPolicyIdsWithServerId 查找服务独立关联的策略IDs
|
// FindFirewallPolicyIdsWithServerId 查找服务独立关联的策略IDs
|
||||||
func (this *HTTPFirewallPolicyDAO) FindFirewallPolicyIdsWithServerId(tx *dbs.Tx, serverId int64) ([]int64, error) {
|
func (this *HTTPFirewallPolicyDAO) FindFirewallPolicyIdsWithServerId(tx *dbs.Tx, serverId int64) ([]int64, error) {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
var result = []int64{}
|
var result = []int64{}
|
||||||
ones, err := this.Query(tx).
|
ones, err := this.Query(tx).
|
||||||
Attr("serverId", serverId).
|
Attr("serverId", serverId).
|
||||||
|
|||||||
@@ -124,8 +124,9 @@ func (this *HTTPRewriteRuleDAO) ComposeRewriteRule(tx *dbs.Tx, rewriteRuleId int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateRewriteRule 创建规则
|
// CreateRewriteRule 创建规则
|
||||||
func (this *HTTPRewriteRuleDAO) CreateRewriteRule(tx *dbs.Tx, pattern string, replace string, mode string, redirectStatus int, isBreak bool, proxyHost string, withQuery bool, isOn bool, condsJSON []byte) (int64, error) {
|
func (this *HTTPRewriteRuleDAO) CreateRewriteRule(tx *dbs.Tx, userId int64, pattern string, replace string, mode string, redirectStatus int, isBreak bool, proxyHost string, withQuery bool, isOn bool, condsJSON []byte) (int64, error) {
|
||||||
var op = NewHTTPRewriteRuleOperator()
|
var op = NewHTTPRewriteRuleOperator()
|
||||||
|
op.UserId = userId
|
||||||
op.State = HTTPRewriteRuleStateEnabled
|
op.State = HTTPRewriteRuleStateEnabled
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
|
|
||||||
@@ -172,6 +173,34 @@ func (this *HTTPRewriteRuleDAO) UpdateRewriteRule(tx *dbs.Tx, rewriteRuleId int6
|
|||||||
return this.NotifyUpdate(tx, rewriteRuleId)
|
return this.NotifyUpdate(tx, rewriteRuleId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *HTTPRewriteRuleDAO) CheckUserRewriteRule(tx *dbs.Tx, userId int64, rewriteRuleId int64) error {
|
||||||
|
if rewriteRuleId <= 0 {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
exists, err := this.Query(tx).
|
||||||
|
Pk(rewriteRuleId).
|
||||||
|
Attr("userId", userId).
|
||||||
|
Exist()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithRewriteRuleId(tx, rewriteRuleId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if webId <= 0 {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return SharedHTTPWebDAO.CheckUserWeb(tx, userId, webId)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *HTTPRewriteRuleDAO) NotifyUpdate(tx *dbs.Tx, rewriteRuleId int64) error {
|
func (this *HTTPRewriteRuleDAO) NotifyUpdate(tx *dbs.Tx, rewriteRuleId int64) error {
|
||||||
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithRewriteRuleId(tx, rewriteRuleId)
|
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithRewriteRuleId(tx, rewriteRuleId)
|
||||||
|
|||||||
@@ -151,6 +151,18 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, isLocationOrGr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optimization
|
||||||
|
if IsNotNull(web.Optimization) {
|
||||||
|
var optimizationConfig = serverconfigs.NewHTTPPageOptimizationConfig()
|
||||||
|
err = json.Unmarshal(web.Optimization, optimizationConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if this.shouldCompose(isLocationOrGroup, forNode, optimizationConfig.IsPrior, true) {
|
||||||
|
config.Optimization = optimizationConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// charset
|
// charset
|
||||||
if IsNotNull(web.Charset) {
|
if IsNotNull(web.Charset) {
|
||||||
var charsetConfig = &serverconfigs.HTTPCharsetConfig{}
|
var charsetConfig = &serverconfigs.HTTPCharsetConfig{}
|
||||||
@@ -550,7 +562,20 @@ func (this *HTTPWebDAO) CreateWeb(tx *dbs.Tx, adminId int64, userId int64, rootJ
|
|||||||
if len(rootJSON) > 0 {
|
if len(rootJSON) > 0 {
|
||||||
op.Root = JSONBytes(rootJSON)
|
op.Root = JSONBytes(rootJSON)
|
||||||
}
|
}
|
||||||
err := this.Save(tx, op)
|
|
||||||
|
// 设置默认的remote-addr
|
||||||
|
// set default remote-addr config
|
||||||
|
var remoteAddrConfig = &serverconfigs.HTTPRemoteAddrConfig{
|
||||||
|
IsOn: true,
|
||||||
|
Value: "${rawRemoteAddr}",
|
||||||
|
}
|
||||||
|
remoteAddrConfigJSON, err := json.Marshal(remoteAddrConfig)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.RemoteAddr = remoteAddrConfigJSON
|
||||||
|
|
||||||
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -574,14 +599,42 @@ func (this *HTTPWebDAO) UpdateWeb(tx *dbs.Tx, webId int64, rootJSON []byte) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateWebCompression 修改压缩配置
|
// UpdateWebCompression 修改压缩配置
|
||||||
func (this *HTTPWebDAO) UpdateWebCompression(tx *dbs.Tx, webId int64, compressionConfig []byte) error {
|
func (this *HTTPWebDAO) UpdateWebCompression(tx *dbs.Tx, webId int64, compressionConfig *serverconfigs.HTTPCompressionConfig) error {
|
||||||
if webId <= 0 {
|
if webId <= 0 {
|
||||||
return errors.New("invalid webId")
|
return errors.New("invalid webId")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compressionJSON, err := json.Marshal(compressionConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var op = NewHTTPWebOperator()
|
var op = NewHTTPWebOperator()
|
||||||
op.Id = webId
|
op.Id = webId
|
||||||
op.Compression = JSONBytes(compressionConfig)
|
op.Compression = compressionJSON
|
||||||
err := this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyUpdate(tx, webId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateWebOptimization 修改页面优化配置
|
||||||
|
func (this *HTTPWebDAO) UpdateWebOptimization(tx *dbs.Tx, webId int64, optimizationConfig *serverconfigs.HTTPPageOptimizationConfig) error {
|
||||||
|
if webId <= 0 {
|
||||||
|
return errors.New("invalid webId")
|
||||||
|
}
|
||||||
|
|
||||||
|
optimizationJSON, err := json.Marshal(optimizationConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var op = NewHTTPWebOperator()
|
||||||
|
op.Id = webId
|
||||||
|
op.Optimization = optimizationJSON
|
||||||
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,47 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
HTTPWebField_Id dbs.FieldName = "id" // ID
|
||||||
|
HTTPWebField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
HTTPWebField_TemplateId dbs.FieldName = "templateId" // 模版ID
|
||||||
|
HTTPWebField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
HTTPWebField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
HTTPWebField_State dbs.FieldName = "state" // 状态
|
||||||
|
HTTPWebField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
HTTPWebField_Root dbs.FieldName = "root" // 根目录
|
||||||
|
HTTPWebField_Charset dbs.FieldName = "charset" // 字符集
|
||||||
|
HTTPWebField_Shutdown dbs.FieldName = "shutdown" // 临时关闭页面配置
|
||||||
|
HTTPWebField_Pages dbs.FieldName = "pages" // 特殊页面
|
||||||
|
HTTPWebField_RedirectToHttps dbs.FieldName = "redirectToHttps" // 跳转到HTTPS设置
|
||||||
|
HTTPWebField_Indexes dbs.FieldName = "indexes" // 首页文件列表
|
||||||
|
HTTPWebField_MaxRequestBodySize dbs.FieldName = "maxRequestBodySize" // 最大允许的请求内容尺寸
|
||||||
|
HTTPWebField_RequestHeader dbs.FieldName = "requestHeader" // 请求Header配置
|
||||||
|
HTTPWebField_ResponseHeader dbs.FieldName = "responseHeader" // 响应Header配置
|
||||||
|
HTTPWebField_AccessLog dbs.FieldName = "accessLog" // 访问日志配置
|
||||||
|
HTTPWebField_Stat dbs.FieldName = "stat" // 统计配置
|
||||||
|
HTTPWebField_Gzip dbs.FieldName = "gzip" // Gzip配置(v0.3.2弃用)
|
||||||
|
HTTPWebField_Compression dbs.FieldName = "compression" // 压缩配置
|
||||||
|
HTTPWebField_Cache dbs.FieldName = "cache" // 缓存配置
|
||||||
|
HTTPWebField_Firewall dbs.FieldName = "firewall" // 防火墙设置
|
||||||
|
HTTPWebField_Locations dbs.FieldName = "locations" // 路由规则配置
|
||||||
|
HTTPWebField_Websocket dbs.FieldName = "websocket" // Websocket设置
|
||||||
|
HTTPWebField_RewriteRules dbs.FieldName = "rewriteRules" // 重写规则配置
|
||||||
|
HTTPWebField_HostRedirects dbs.FieldName = "hostRedirects" // 域名跳转
|
||||||
|
HTTPWebField_Fastcgi dbs.FieldName = "fastcgi" // Fastcgi配置
|
||||||
|
HTTPWebField_Auth dbs.FieldName = "auth" // 认证策略配置
|
||||||
|
HTTPWebField_Webp dbs.FieldName = "webp" // WebP配置
|
||||||
|
HTTPWebField_RemoteAddr dbs.FieldName = "remoteAddr" // 客户端IP配置
|
||||||
|
HTTPWebField_MergeSlashes dbs.FieldName = "mergeSlashes" // 是否合并路径中的斜杠
|
||||||
|
HTTPWebField_RequestLimit dbs.FieldName = "requestLimit" // 请求限制
|
||||||
|
HTTPWebField_RequestScripts dbs.FieldName = "requestScripts" // 请求脚本
|
||||||
|
HTTPWebField_Uam dbs.FieldName = "uam" // UAM设置
|
||||||
|
HTTPWebField_Cc dbs.FieldName = "cc" // CC设置
|
||||||
|
HTTPWebField_Referers dbs.FieldName = "referers" // 防盗链设置
|
||||||
|
HTTPWebField_UserAgent dbs.FieldName = "userAgent" // UserAgent设置
|
||||||
|
HTTPWebField_Optimization dbs.FieldName = "optimization" // 页面优化配置
|
||||||
|
)
|
||||||
|
|
||||||
// HTTPWeb HTTP Web
|
// HTTPWeb HTTP Web
|
||||||
type HTTPWeb struct {
|
type HTTPWeb struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -41,6 +82,7 @@ type HTTPWeb struct {
|
|||||||
Cc dbs.JSON `field:"cc"` // CC设置
|
Cc dbs.JSON `field:"cc"` // CC设置
|
||||||
Referers dbs.JSON `field:"referers"` // 防盗链设置
|
Referers dbs.JSON `field:"referers"` // 防盗链设置
|
||||||
UserAgent dbs.JSON `field:"userAgent"` // UserAgent设置
|
UserAgent dbs.JSON `field:"userAgent"` // UserAgent设置
|
||||||
|
Optimization dbs.JSON `field:"optimization"` // 页面优化配置
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPWebOperator struct {
|
type HTTPWebOperator struct {
|
||||||
@@ -81,6 +123,7 @@ type HTTPWebOperator struct {
|
|||||||
Cc any // CC设置
|
Cc any // CC设置
|
||||||
Referers any // 防盗链设置
|
Referers any // 防盗链设置
|
||||||
UserAgent any // UserAgent设置
|
UserAgent any // UserAgent设置
|
||||||
|
Optimization any // 页面优化配置
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPWebOperator() *HTTPWebOperator {
|
func NewHTTPWebOperator() *HTTPWebOperator {
|
||||||
|
|||||||
@@ -339,7 +339,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: types.Uint16(country.Id),
|
Id: types.Uint16(country.ValueId),
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
Codes: country.AllCodes(),
|
Codes: country.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -354,7 +354,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: types.Uint16(province.Id),
|
Id: types.Uint16(province.ValueId),
|
||||||
Name: province.DisplayName(),
|
Name: province.DisplayName(),
|
||||||
Codes: province.AllCodes(),
|
Codes: province.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -369,7 +369,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: city.Id,
|
Id: city.ValueId,
|
||||||
Name: city.DisplayName(),
|
Name: city.DisplayName(),
|
||||||
Codes: city.AllCodes(),
|
Codes: city.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -384,7 +384,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: town.Id,
|
Id: town.ValueId,
|
||||||
Name: town.DisplayName(),
|
Name: town.DisplayName(),
|
||||||
Codes: town.AllCodes(),
|
Codes: town.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -399,7 +399,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: types.Uint16(provider.Id),
|
Id: types.Uint16(provider.ValueId),
|
||||||
Name: provider.DisplayName(),
|
Name: provider.DisplayName(),
|
||||||
Codes: provider.AllCodes(),
|
Codes: provider.AllCodes(),
|
||||||
})
|
})
|
||||||
@@ -440,35 +440,35 @@ func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64)
|
|||||||
var countryMap = map[string]int64{} // countryName => countryId
|
var countryMap = map[string]int64{} // countryName => countryId
|
||||||
for _, country := range dbCountries {
|
for _, country := range dbCountries {
|
||||||
for _, code := range country.AllCodes() {
|
for _, code := range country.AllCodes() {
|
||||||
countryMap[code] = int64(country.Id)
|
countryMap[code] = int64(country.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var provinceMap = map[string]int64{} // countryId_provinceName => provinceId
|
var provinceMap = map[string]int64{} // countryId_provinceName => provinceId
|
||||||
for _, province := range dbProvinces {
|
for _, province := range dbProvinces {
|
||||||
for _, code := range province.AllCodes() {
|
for _, code := range province.AllCodes() {
|
||||||
provinceMap[types.String(province.CountryId)+"_"+code] = int64(province.Id)
|
provinceMap[types.String(province.CountryId)+"_"+code] = int64(province.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cityMap = map[string]int64{} // provinceId_cityName => cityId
|
var cityMap = map[string]int64{} // provinceId_cityName => cityId
|
||||||
for _, city := range dbCities {
|
for _, city := range dbCities {
|
||||||
for _, code := range city.AllCodes() {
|
for _, code := range city.AllCodes() {
|
||||||
cityMap[types.String(city.ProvinceId)+"_"+code] = int64(city.Id)
|
cityMap[types.String(city.ProvinceId)+"_"+code] = int64(city.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var townMap = map[string]int64{} // cityId_townName => townId
|
var townMap = map[string]int64{} // cityId_townName => townId
|
||||||
for _, town := range dbTowns {
|
for _, town := range dbTowns {
|
||||||
for _, code := range town.AllCodes() {
|
for _, code := range town.AllCodes() {
|
||||||
townMap[types.String(town.CityId)+"_"+code] = int64(town.Id)
|
townMap[types.String(town.CityId)+"_"+code] = int64(town.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var providerMap = map[string]int64{} // providerName => providerId
|
var providerMap = map[string]int64{} // providerName => providerId
|
||||||
for _, provider := range dbProviders {
|
for _, provider := range dbProviders {
|
||||||
for _, code := range provider.AllCodes() {
|
for _, code := range provider.AllCodes() {
|
||||||
providerMap[code] = int64(provider.Id)
|
providerMap[code] = int64(provider.ValueId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
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/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
|
||||||
_ "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"
|
||||||
@@ -36,7 +38,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateLog 创建管理员日志
|
// CreateLog 创建管理员日志
|
||||||
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, langMessageCode langs.MessageCode, langMessageArgs []any) error {
|
||||||
var op = NewLogOperator()
|
var op = NewLogOperator()
|
||||||
op.Level = level
|
op.Level = level
|
||||||
op.Description = utils.LimitString(description, 1000)
|
op.Description = utils.LimitString(description, 1000)
|
||||||
@@ -53,6 +55,16 @@ func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level
|
|||||||
op.ProviderId = adminId
|
op.ProviderId = adminId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// i18n
|
||||||
|
op.LangMessageCode = langMessageCode
|
||||||
|
if len(langMessageArgs) > 0 {
|
||||||
|
langMessageArgsJSON, err := json.Marshal(langMessageArgs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.LangMessageArgs = langMessageArgsJSON
|
||||||
|
}
|
||||||
|
|
||||||
op.Day = timeutil.Format("Ymd")
|
op.Day = timeutil.Format("Ymd")
|
||||||
op.Type = LogTypeAdmin
|
op.Type = LogTypeAdmin
|
||||||
err := this.Save(tx, op)
|
err := this.Save(tx, op)
|
||||||
|
|||||||
@@ -1,34 +1,60 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
// 操作日志
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
LogField_Id dbs.FieldName = "id" // ID
|
||||||
|
LogField_Level dbs.FieldName = "level" // 级别
|
||||||
|
LogField_Description dbs.FieldName = "description" // 描述
|
||||||
|
LogField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
LogField_Action dbs.FieldName = "action" // 动作
|
||||||
|
LogField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
LogField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
LogField_ProviderId dbs.FieldName = "providerId" // 供应商ID
|
||||||
|
LogField_Ip dbs.FieldName = "ip" // IP地址
|
||||||
|
LogField_Type dbs.FieldName = "type" // 类型:admin, user
|
||||||
|
LogField_Day dbs.FieldName = "day" // 日期
|
||||||
|
LogField_BillId dbs.FieldName = "billId" // 账单ID
|
||||||
|
LogField_LangMessageCode dbs.FieldName = "langMessageCode" // 多语言消息代号
|
||||||
|
LogField_LangMessageArgs dbs.FieldName = "langMessageArgs" // 多语言参数
|
||||||
|
LogField_Params dbs.FieldName = "params" // 关联对象参数
|
||||||
|
)
|
||||||
|
|
||||||
|
// Log 操作日志
|
||||||
type Log struct {
|
type Log struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
Level string `field:"level"` // 级别
|
Level string `field:"level"` // 级别
|
||||||
Description string `field:"description"` // 描述
|
Description string `field:"description"` // 描述
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
Action string `field:"action"` // 动作
|
Action string `field:"action"` // 动作
|
||||||
UserId uint32 `field:"userId"` // 用户ID
|
UserId uint32 `field:"userId"` // 用户ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
ProviderId uint32 `field:"providerId"` // 供应商ID
|
ProviderId uint32 `field:"providerId"` // 供应商ID
|
||||||
Ip string `field:"ip"` // IP地址
|
Ip string `field:"ip"` // IP地址
|
||||||
Type string `field:"type"` // 类型:admin, user
|
Type string `field:"type"` // 类型:admin, user
|
||||||
Day string `field:"day"` // 日期
|
Day string `field:"day"` // 日期
|
||||||
BillId uint32 `field:"billId"` // 账单ID
|
BillId uint32 `field:"billId"` // 账单ID
|
||||||
|
LangMessageCode string `field:"langMessageCode"` // 多语言消息代号
|
||||||
|
LangMessageArgs dbs.JSON `field:"langMessageArgs"` // 多语言参数
|
||||||
|
Params dbs.JSON `field:"params"` // 关联对象参数
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogOperator struct {
|
type LogOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
Level interface{} // 级别
|
Level any // 级别
|
||||||
Description interface{} // 描述
|
Description any // 描述
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt any // 创建时间
|
||||||
Action interface{} // 动作
|
Action any // 动作
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
ProviderId interface{} // 供应商ID
|
ProviderId any // 供应商ID
|
||||||
Ip interface{} // IP地址
|
Ip any // IP地址
|
||||||
Type interface{} // 类型:admin, user
|
Type any // 类型:admin, user
|
||||||
Day interface{} // 日期
|
Day any // 日期
|
||||||
BillId interface{} // 账单ID
|
BillId any // 账单ID
|
||||||
|
LangMessageCode any // 多语言消息代号
|
||||||
|
LangMessageArgs any // 多语言参数
|
||||||
|
Params any // 关联对象参数
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLogOperator() *LogOperator {
|
func NewLogOperator() *LogOperator {
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ func (this *MonitorNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, statusJSO
|
|||||||
func (this *MonitorNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
func (this *MonitorNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(MonitorNodeStateEnabled).
|
State(MonitorNodeStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
Where("status IS NOT NULL").
|
Where("status IS NOT NULL").
|
||||||
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
||||||
Param("version", utils.VersionToLong(version)).
|
Param("version", utils.VersionToLong(version)).
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ func (this *NodeClusterDAO) FindNodeClusterName(tx *dbs.Tx, clusterId int64) (st
|
|||||||
// FindAllEnableClusters 查找所有可用的集群
|
// FindAllEnableClusters 查找所有可用的集群
|
||||||
func (this *NodeClusterDAO) FindAllEnableClusters(tx *dbs.Tx) (result []*NodeCluster, err error) {
|
func (this *NodeClusterDAO) FindAllEnableClusters(tx *dbs.Tx) (result []*NodeCluster, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
|
Result(NodeClusterField_Id, NodeClusterField_Name, NodeClusterField_IsOn, NodeClusterField_HealthCheck, NodeClusterField_AutoRemoteStart, NodeClusterField_AutoRegister, NodeClusterField_CreatedAt, NodeClusterField_UniqueId, NodeClusterField_Secret).
|
||||||
State(NodeClusterStateEnabled).
|
State(NodeClusterStateEnabled).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
Desc("isPinned").
|
Desc("isPinned").
|
||||||
@@ -175,7 +176,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
|
|||||||
|
|
||||||
// 全局服务配置
|
// 全局服务配置
|
||||||
if globalServerConfig == nil {
|
if globalServerConfig == nil {
|
||||||
globalServerConfig = serverconfigs.DefaultGlobalServerConfig()
|
globalServerConfig = serverconfigs.NewGlobalServerConfig()
|
||||||
}
|
}
|
||||||
globalServerConfigJSON, err := json.Marshal(globalServerConfig)
|
globalServerConfigJSON, err := json.Marshal(globalServerConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -262,19 +263,40 @@ func (this *NodeClusterDAO) CountAllEnabledClusters(tx *dbs.Tx, keyword string)
|
|||||||
|
|
||||||
// ListEnabledClusters 列出单页集群
|
// ListEnabledClusters 列出单页集群
|
||||||
func (this *NodeClusterDAO) ListEnabledClusters(tx *dbs.Tx, keyword string, offset, size int64) (result []*NodeCluster, err error) {
|
func (this *NodeClusterDAO) ListEnabledClusters(tx *dbs.Tx, keyword string, offset, size int64) (result []*NodeCluster, err error) {
|
||||||
query := this.Query(tx).
|
var query = this.Query(tx).
|
||||||
State(NodeClusterStateEnabled)
|
State(NodeClusterStateEnabled)
|
||||||
if len(keyword) > 0 {
|
if len(keyword) > 0 {
|
||||||
query.Where("(name LIKE :keyword OR dnsName like :keyword OR (dnsDomainId > 0 AND dnsDomainId IN (SELECT id FROM "+dns.SharedDNSDomainDAO.Table+" WHERE name LIKE :keyword AND state=1)))").
|
query.Where("(name LIKE :keyword OR dnsName like :keyword OR (dnsDomainId > 0 AND dnsDomainId IN (SELECT id FROM "+dns.SharedDNSDomainDAO.Table+" WHERE name LIKE :keyword AND state=1)))").
|
||||||
Param("keyword", dbutils.QuoteLike(keyword))
|
Param("keyword", dbutils.QuoteLike(keyword))
|
||||||
}
|
}
|
||||||
_, err = query.
|
_, err = query.
|
||||||
|
Result(
|
||||||
|
NodeClusterField_Id,
|
||||||
|
NodeClusterField_Name,
|
||||||
|
NodeClusterField_IsOn,
|
||||||
|
NodeClusterField_IsPinned,
|
||||||
|
NodeClusterField_InstallDir,
|
||||||
|
NodeClusterField_HttpFirewallPolicyId,
|
||||||
|
NodeClusterField_AdminId,
|
||||||
|
NodeClusterField_IsOn,
|
||||||
|
NodeClusterField_IsAD,
|
||||||
|
NodeClusterField_UserId,
|
||||||
|
NodeClusterField_DnsName,
|
||||||
|
NodeClusterField_DnsDomainId,
|
||||||
|
NodeClusterField_Dns,
|
||||||
|
NodeClusterField_CreatedAt,
|
||||||
|
NodeClusterField_UniqueId,
|
||||||
|
NodeClusterField_Secret,
|
||||||
|
NodeClusterField_GrantId,
|
||||||
|
NodeClusterField_TimeZone,
|
||||||
|
).
|
||||||
Offset(offset).
|
Offset(offset).
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
Desc("isPinned").
|
Desc("isPinned").
|
||||||
DescPk().
|
DescPk().
|
||||||
FindAll()
|
FindAll()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -996,7 +1018,7 @@ func (this *NodeClusterDAO) FindClusterBasicInfo(tx *dbs.Tx, clusterId int64, ca
|
|||||||
cluster, err := this.Query(tx).
|
cluster, err := this.Query(tx).
|
||||||
Pk(clusterId).
|
Pk(clusterId).
|
||||||
State(NodeClusterStateEnabled).
|
State(NodeClusterStateEnabled).
|
||||||
Result("id", "name", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "uam", "cc", "httpPages", "isOn", "ddosProtection", "clock", "globalServerConfig", "autoInstallNftables").
|
Result("id", "name", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "uam", "cc", "httpPages", "http3", "isOn", "ddosProtection", "clock", "globalServerConfig", "autoInstallNftables").
|
||||||
Find()
|
Find()
|
||||||
if err != nil || cluster == nil {
|
if err != nil || cluster == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1113,11 +1135,12 @@ func (this *NodeClusterDAO) FindClusterUAMPolicy(tx *dbs.Tx, clusterId int64, ca
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var policy = nodeconfigs.NewUAMPolicy()
|
||||||
|
|
||||||
if IsNull(uamJSON) {
|
if IsNull(uamJSON) {
|
||||||
return nodeconfigs.DefaultUAMPolicy, nil
|
return policy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var policy = &nodeconfigs.UAMPolicy{}
|
|
||||||
err = json.Unmarshal(uamJSON, policy)
|
err = json.Unmarshal(uamJSON, policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1184,6 +1207,65 @@ func (this *NodeClusterDAO) FindClusterHTTPCCPolicy(tx *dbs.Tx, clusterId int64,
|
|||||||
return policy, nil
|
return policy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateClusterHTTP3Policy 修改HTTP3策略设置
|
||||||
|
func (this *NodeClusterDAO) UpdateClusterHTTP3Policy(tx *dbs.Tx, clusterId int64, http3Policy *nodeconfigs.HTTP3Policy) error {
|
||||||
|
if http3Policy == nil {
|
||||||
|
err := this.Query(tx).
|
||||||
|
Pk(clusterId).
|
||||||
|
Set("http3", dbs.SQL("null")).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyHTTP3Update(tx, clusterId)
|
||||||
|
}
|
||||||
|
|
||||||
|
http3PolicyJSON, err := json.Marshal(http3Policy)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(clusterId).
|
||||||
|
Set("http3", http3PolicyJSON).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyHTTP3Update(tx, clusterId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindClusterHTTP3Policy 查询HTTP3策略设置
|
||||||
|
func (this *NodeClusterDAO) FindClusterHTTP3Policy(tx *dbs.Tx, clusterId int64, cacheMap *utils.CacheMap) (*nodeconfigs.HTTP3Policy, error) {
|
||||||
|
var cacheKey = this.Table + ":FindClusterHTTP3Policy:" + types.String(clusterId)
|
||||||
|
if cacheMap != nil {
|
||||||
|
cache, ok := cacheMap.Get(cacheKey)
|
||||||
|
if ok {
|
||||||
|
return cache.(*nodeconfigs.HTTP3Policy), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
http3PolicyJSON, err := this.Query(tx).
|
||||||
|
Pk(clusterId).
|
||||||
|
Result("http3").
|
||||||
|
FindJSONCol()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsNull(http3PolicyJSON) {
|
||||||
|
return nodeconfigs.NewHTTP3Policy(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var policy = nodeconfigs.NewHTTP3Policy()
|
||||||
|
err = json.Unmarshal(http3PolicyJSON, policy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return policy, nil
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateClusterHTTPPagesPolicy 修改自定义页面设置
|
// UpdateClusterHTTPPagesPolicy 修改自定义页面设置
|
||||||
func (this *NodeClusterDAO) UpdateClusterHTTPPagesPolicy(tx *dbs.Tx, clusterId int64, httpPagesPolicy *nodeconfigs.HTTPPagesPolicy) error {
|
func (this *NodeClusterDAO) UpdateClusterHTTPPagesPolicy(tx *dbs.Tx, clusterId int64, httpPagesPolicy *nodeconfigs.HTTPPagesPolicy) error {
|
||||||
if httpPagesPolicy == nil {
|
if httpPagesPolicy == nil {
|
||||||
@@ -1314,7 +1396,7 @@ func (this *NodeClusterDAO) FindClusterGlobalServerConfig(tx *dbs.Tx, clusterId
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = serverconfigs.DefaultGlobalServerConfig()
|
var config = serverconfigs.NewGlobalServerConfig()
|
||||||
if IsNull(configJSON) {
|
if IsNull(configJSON) {
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
@@ -1330,7 +1412,7 @@ func (this *NodeClusterDAO) FindClusterGlobalServerConfig(tx *dbs.Tx, clusterId
|
|||||||
// UpdateClusterGlobalServerConfig 修改全局服务配置
|
// UpdateClusterGlobalServerConfig 修改全局服务配置
|
||||||
func (this *NodeClusterDAO) UpdateClusterGlobalServerConfig(tx *dbs.Tx, clusterId int64, config *serverconfigs.GlobalServerConfig) error {
|
func (this *NodeClusterDAO) UpdateClusterGlobalServerConfig(tx *dbs.Tx, clusterId int64, config *serverconfigs.GlobalServerConfig) error {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = serverconfigs.DefaultGlobalServerConfig()
|
config = serverconfigs.NewGlobalServerConfig()
|
||||||
}
|
}
|
||||||
configJSON, err := json.Marshal(config)
|
configJSON, err := json.Marshal(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1362,6 +1444,11 @@ func (this *NodeClusterDAO) NotifyHTTPCCUpdate(tx *dbs.Tx, clusterId int64) erro
|
|||||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTPCCPolicyChanged)
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTPCCPolicyChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotifyHTTP3Update 通知HTTP3更新
|
||||||
|
func (this *NodeClusterDAO) NotifyHTTP3Update(tx *dbs.Tx, clusterId int64) error {
|
||||||
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTP3PolicyChanged)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyHTTPPagesPolicyUpdate 通知HTTP Pages更新
|
// NotifyHTTPPagesPolicyUpdate 通知HTTP Pages更新
|
||||||
func (this *NodeClusterDAO) NotifyHTTPPagesPolicyUpdate(tx *dbs.Tx, clusterId int64) error {
|
func (this *NodeClusterDAO) NotifyHTTPPagesPolicyUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTPPagesPolicyChanged)
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTPPagesPolicyChanged)
|
||||||
|
|||||||
@@ -2,6 +2,49 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
NodeClusterField_Id dbs.FieldName = "id" // ID
|
||||||
|
NodeClusterField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
NodeClusterField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
NodeClusterField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
NodeClusterField_Name dbs.FieldName = "name" // 名称
|
||||||
|
NodeClusterField_UseAllAPINodes dbs.FieldName = "useAllAPINodes" // 是否使用所有API节点
|
||||||
|
NodeClusterField_ApiNodes dbs.FieldName = "apiNodes" // 使用的API节点
|
||||||
|
NodeClusterField_InstallDir dbs.FieldName = "installDir" // 安装目录
|
||||||
|
NodeClusterField_Order dbs.FieldName = "order" // 排序
|
||||||
|
NodeClusterField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
NodeClusterField_GrantId dbs.FieldName = "grantId" // 默认认证方式
|
||||||
|
NodeClusterField_SshParams dbs.FieldName = "sshParams" // SSH默认参数
|
||||||
|
NodeClusterField_State dbs.FieldName = "state" // 状态
|
||||||
|
NodeClusterField_AutoRegister dbs.FieldName = "autoRegister" // 是否开启自动注册
|
||||||
|
NodeClusterField_UniqueId dbs.FieldName = "uniqueId" // 唯一ID
|
||||||
|
NodeClusterField_Secret dbs.FieldName = "secret" // 密钥
|
||||||
|
NodeClusterField_HealthCheck dbs.FieldName = "healthCheck" // 健康检查
|
||||||
|
NodeClusterField_DnsName dbs.FieldName = "dnsName" // DNS名称
|
||||||
|
NodeClusterField_DnsDomainId dbs.FieldName = "dnsDomainId" // 域名ID
|
||||||
|
NodeClusterField_Dns dbs.FieldName = "dns" // DNS配置
|
||||||
|
NodeClusterField_Toa dbs.FieldName = "toa" // TOA配置
|
||||||
|
NodeClusterField_CachePolicyId dbs.FieldName = "cachePolicyId" // 缓存策略ID
|
||||||
|
NodeClusterField_HttpFirewallPolicyId dbs.FieldName = "httpFirewallPolicyId" // WAF策略ID
|
||||||
|
NodeClusterField_AccessLog dbs.FieldName = "accessLog" // 访问日志设置
|
||||||
|
NodeClusterField_SystemServices dbs.FieldName = "systemServices" // 系统服务设置
|
||||||
|
NodeClusterField_TimeZone dbs.FieldName = "timeZone" // 时区
|
||||||
|
NodeClusterField_NodeMaxThreads dbs.FieldName = "nodeMaxThreads" // 节点最大线程数
|
||||||
|
NodeClusterField_DdosProtection dbs.FieldName = "ddosProtection" // DDoS防护设置
|
||||||
|
NodeClusterField_AutoOpenPorts dbs.FieldName = "autoOpenPorts" // 是否自动尝试开放端口
|
||||||
|
NodeClusterField_IsPinned dbs.FieldName = "isPinned" // 是否置顶
|
||||||
|
NodeClusterField_Webp dbs.FieldName = "webp" // WebP设置
|
||||||
|
NodeClusterField_Uam dbs.FieldName = "uam" // UAM设置
|
||||||
|
NodeClusterField_Clock dbs.FieldName = "clock" // 时钟配置
|
||||||
|
NodeClusterField_GlobalServerConfig dbs.FieldName = "globalServerConfig" // 全局服务配置
|
||||||
|
NodeClusterField_AutoRemoteStart dbs.FieldName = "autoRemoteStart" // 自动远程启动
|
||||||
|
NodeClusterField_AutoInstallNftables dbs.FieldName = "autoInstallNftables" // 自动安装nftables
|
||||||
|
NodeClusterField_IsAD dbs.FieldName = "isAD" // 是否为高防集群
|
||||||
|
NodeClusterField_HttpPages dbs.FieldName = "httpPages" // 自定义页面设置
|
||||||
|
NodeClusterField_Cc dbs.FieldName = "cc" // CC设置
|
||||||
|
NodeClusterField_Http3 dbs.FieldName = "http3" // HTTP3设置
|
||||||
|
)
|
||||||
|
|
||||||
// NodeCluster 节点集群
|
// NodeCluster 节点集群
|
||||||
type NodeCluster struct {
|
type NodeCluster struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -43,6 +86,7 @@ type NodeCluster struct {
|
|||||||
IsAD bool `field:"isAD"` // 是否为高防集群
|
IsAD bool `field:"isAD"` // 是否为高防集群
|
||||||
HttpPages dbs.JSON `field:"httpPages"` // 自定义页面设置
|
HttpPages dbs.JSON `field:"httpPages"` // 自定义页面设置
|
||||||
Cc dbs.JSON `field:"cc"` // CC设置
|
Cc dbs.JSON `field:"cc"` // CC设置
|
||||||
|
Http3 dbs.JSON `field:"http3"` // HTTP3设置
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeClusterOperator struct {
|
type NodeClusterOperator struct {
|
||||||
@@ -85,6 +129,7 @@ type NodeClusterOperator struct {
|
|||||||
IsAD any // 是否为高防集群
|
IsAD any // 是否为高防集群
|
||||||
HttpPages any // 自定义页面设置
|
HttpPages any // 自定义页面设置
|
||||||
Cc any // CC设置
|
Cc any // CC设置
|
||||||
|
Http3 any // HTTP3设置
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNodeClusterOperator() *NodeClusterOperator {
|
func NewNodeClusterOperator() *NodeClusterOperator {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ func (this *NodeCluster) DecodeClock() *nodeconfigs.ClockConfig {
|
|||||||
|
|
||||||
// DecodeGlobalServerConfig 解析全局服务配置
|
// DecodeGlobalServerConfig 解析全局服务配置
|
||||||
func (this *NodeCluster) DecodeGlobalServerConfig() *serverconfigs.GlobalServerConfig {
|
func (this *NodeCluster) DecodeGlobalServerConfig() *serverconfigs.GlobalServerConfig {
|
||||||
var config = serverconfigs.DefaultGlobalServerConfig()
|
var config = serverconfigs.NewGlobalServerConfig()
|
||||||
if IsNotNull(this.GlobalServerConfig) {
|
if IsNotNull(this.GlobalServerConfig) {
|
||||||
err := json.Unmarshal(this.GlobalServerConfig, config)
|
err := json.Unmarshal(this.GlobalServerConfig, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -295,6 +295,7 @@ func (this *NodeDAO) CountAllEnabledNodes(tx *dbs.Tx) (int64, error) {
|
|||||||
func (this *NodeDAO) CountAllEnabledOfflineNodes(tx *dbs.Tx) (int64, error) {
|
func (this *NodeDAO) CountAllEnabledOfflineNodes(tx *dbs.Tx) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(NodeStateEnabled).
|
State(NodeStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
Where("clusterId IN (SELECT id FROM "+SharedNodeClusterDAO.Table+" WHERE state=:clusterState)").
|
Where("clusterId IN (SELECT id FROM "+SharedNodeClusterDAO.Table+" WHERE state=:clusterState)").
|
||||||
Param("clusterState", NodeClusterStateEnabled).
|
Param("clusterState", NodeClusterStateEnabled).
|
||||||
Where("(status IS NULL OR NOT JSON_EXTRACT(status, '$.isActive') OR UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>60)").
|
Where("(status IS NULL OR NOT JSON_EXTRACT(status, '$.isActive') OR UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>60)").
|
||||||
@@ -1086,6 +1087,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
config.WebPImagePolicies = map[int64]*nodeconfigs.WebPImagePolicy{}
|
config.WebPImagePolicies = map[int64]*nodeconfigs.WebPImagePolicy{}
|
||||||
config.UAMPolicies = map[int64]*nodeconfigs.UAMPolicy{}
|
config.UAMPolicies = map[int64]*nodeconfigs.UAMPolicy{}
|
||||||
config.HTTPCCPolicies = map[int64]*nodeconfigs.HTTPCCPolicy{}
|
config.HTTPCCPolicies = map[int64]*nodeconfigs.HTTPCCPolicy{}
|
||||||
|
config.HTTP3Policies = map[int64]*nodeconfigs.HTTP3Policy{}
|
||||||
config.HTTPPagesPolicies = map[int64]*nodeconfigs.HTTPPagesPolicy{}
|
config.HTTPPagesPolicies = map[int64]*nodeconfigs.HTTPPagesPolicy{}
|
||||||
var allowIPMaps = map[string]bool{}
|
var allowIPMaps = map[string]bool{}
|
||||||
for _, clusterId := range clusterIds {
|
for _, clusterId := range clusterIds {
|
||||||
@@ -1172,7 +1174,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
|
|
||||||
// UAM
|
// UAM
|
||||||
if IsNotNull(nodeCluster.Uam) {
|
if IsNotNull(nodeCluster.Uam) {
|
||||||
var uamPolicy = &nodeconfigs.UAMPolicy{}
|
var uamPolicy = nodeconfigs.NewUAMPolicy()
|
||||||
err = json.Unmarshal(nodeCluster.Uam, uamPolicy)
|
err = json.Unmarshal(nodeCluster.Uam, uamPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1189,7 +1191,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 集成默认设置
|
// 集成默认设置
|
||||||
for i := 0; i < len(serverconfigs.DefaultHTTPCCThresholds); i ++ {
|
for i := 0; i < len(serverconfigs.DefaultHTTPCCThresholds); i++ {
|
||||||
if i < len(ccPolicy.Thresholds) {
|
if i < len(ccPolicy.Thresholds) {
|
||||||
ccPolicy.Thresholds[i].MergeIfEmpty(serverconfigs.DefaultHTTPCCThresholds[i])
|
ccPolicy.Thresholds[i].MergeIfEmpty(serverconfigs.DefaultHTTPCCThresholds[i])
|
||||||
}
|
}
|
||||||
@@ -1198,6 +1200,16 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
config.HTTPCCPolicies[clusterId] = ccPolicy
|
config.HTTPCCPolicies[clusterId] = ccPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTP3 Policy
|
||||||
|
if IsNotNull(nodeCluster.Http3) {
|
||||||
|
var http3Policy = nodeconfigs.NewHTTP3Policy()
|
||||||
|
err = json.Unmarshal(nodeCluster.Http3, http3Policy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.HTTP3Policies[clusterId] = http3Policy
|
||||||
|
}
|
||||||
|
|
||||||
// HTTP Pages Policy
|
// HTTP Pages Policy
|
||||||
if IsNotNull(nodeCluster.HttpPages) {
|
if IsNotNull(nodeCluster.HttpPages) {
|
||||||
var httpPagesPolicy = nodeconfigs.NewHTTPPagesPolicy()
|
var httpPagesPolicy = nodeconfigs.NewHTTPPagesPolicy()
|
||||||
@@ -1473,6 +1485,7 @@ func (this *NodeDAO) FindAllNotInstalledNodesWithClusterId(tx *dbs.Tx, clusterId
|
|||||||
func (this *NodeDAO) CountAllLowerVersionNodesWithClusterId(tx *dbs.Tx, clusterId int64, os string, arch string, version string) (int64, error) {
|
func (this *NodeDAO) CountAllLowerVersionNodesWithClusterId(tx *dbs.Tx, clusterId int64, os string, arch string, version string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(NodeStateEnabled).
|
State(NodeStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
Attr("clusterId", clusterId).
|
Attr("clusterId", clusterId).
|
||||||
Where("status IS NOT NULL").
|
Where("status IS NOT NULL").
|
||||||
Where("JSON_EXTRACT(status, '$.os')=:os").
|
Where("JSON_EXTRACT(status, '$.os')=:os").
|
||||||
@@ -1506,6 +1519,7 @@ func (this *NodeDAO) FindAllLowerVersionNodesWithClusterId(tx *dbs.Tx, clusterId
|
|||||||
func (this *NodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
func (this *NodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(NodeStateEnabled).
|
State(NodeStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
Where("clusterId IN (SELECT id FROM "+SharedNodeClusterDAO.Table+" WHERE state=1)").
|
Where("clusterId IN (SELECT id FROM "+SharedNodeClusterDAO.Table+" WHERE state=1)").
|
||||||
Where("status IS NOT NULL").
|
Where("status IS NOT NULL").
|
||||||
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const (
|
|||||||
NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM策略变化
|
NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM策略变化
|
||||||
NodeTaskTypeHTTPPagesPolicyChanged NodeTaskType = "httpPagesPolicyChanged" // 自定义页面变化
|
NodeTaskTypeHTTPPagesPolicyChanged NodeTaskType = "httpPagesPolicyChanged" // 自定义页面变化
|
||||||
NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC策略变化
|
NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC策略变化
|
||||||
|
NodeTaskTypeHTTP3PolicyChanged NodeTaskType = "http3PolicyChanged" // HTTP3策略变化
|
||||||
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
||||||
|
|
||||||
// NS相关
|
// NS相关
|
||||||
@@ -232,6 +233,12 @@ func (this *NodeTaskDAO) DeleteNodeTasks(tx *dbs.Tx, role string, nodeId int64)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllNodeTasks 删除所有节点相关任务
|
||||||
|
func (this *NodeTaskDAO)DeleteAllNodeTasks(tx *dbs.Tx) error {
|
||||||
|
return this.Query(tx).
|
||||||
|
DeleteQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// FindDoingNodeTasks 查询一个节点的所有任务
|
// FindDoingNodeTasks 查询一个节点的所有任务
|
||||||
func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int64, version int64) (result []*NodeTask, err error) {
|
func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int64, version int64) (result []*NodeTask, err error) {
|
||||||
if nodeId <= 0 {
|
if nodeId <= 0 {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedNodeTrafficDailyStatDAO.Clean(nil, 30) // 只保留N天
|
err := SharedNodeTrafficDailyStatDAO.CleanDefaultDays(nil, 32) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("NodeTrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("NodeTrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -134,11 +134,27 @@ func (this *NodeTrafficDailyStatDAO) SumDailyStat(tx *dbs.Tx, role string, nodeI
|
|||||||
return one.(*NodeTrafficDailyStat), nil
|
return one.(*NodeTrafficDailyStat), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *NodeTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *NodeTrafficDailyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("day", day).
|
Lt("day", day).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *NodeTrafficDailyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.NodeTrafficDailyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.NodeTrafficDailyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ type NSCluster struct {
|
|||||||
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设置
|
||||||
|
Doh dbs.JSON `field:"doh"` // DoH设置
|
||||||
DdosProtection dbs.JSON `field:"ddosProtection"` // DDoS防护设置
|
DdosProtection dbs.JSON `field:"ddosProtection"` // DDoS防护设置
|
||||||
Hosts dbs.JSON `field:"hosts"` // DNS主机地址
|
Hosts dbs.JSON `field:"hosts"` // DNS主机地址
|
||||||
Soa dbs.JSON `field:"soa"` // SOA配置
|
Soa dbs.JSON `field:"soa"` // SOA配置
|
||||||
@@ -39,6 +40,7 @@ type NSClusterOperator struct {
|
|||||||
Tcp any // TCP设置
|
Tcp any // TCP设置
|
||||||
Tls any // TLS设置
|
Tls any // TLS设置
|
||||||
Udp any // UDP设置
|
Udp any // UDP设置
|
||||||
|
Doh any // DoH设置
|
||||||
DdosProtection any // DDoS防护设置
|
DdosProtection any // DDoS防护设置
|
||||||
Hosts any // DNS主机地址
|
Hosts any // DNS主机地址
|
||||||
Soa any // SOA配置
|
Soa any // SOA配置
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ func (this *NSNodeDAO) CountAllLowerVersionNodesWithClusterId(tx *dbs.Tx, cluste
|
|||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(NSNodeStateEnabled).
|
State(NSNodeStateEnabled).
|
||||||
Attr("clusterId", clusterId).
|
Attr("clusterId", clusterId).
|
||||||
|
Attr("isOn", true).
|
||||||
Where("status IS NOT NULL").
|
Where("status IS NOT NULL").
|
||||||
Where("JSON_EXTRACT(status, '$.os')=:os").
|
Where("JSON_EXTRACT(status, '$.os')=:os").
|
||||||
Where("JSON_EXTRACT(status, '$.arch')=:arch").
|
Where("JSON_EXTRACT(status, '$.arch')=:arch").
|
||||||
@@ -161,6 +162,7 @@ func (this *NSNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, nodeStatus *no
|
|||||||
func (this *NSNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
func (this *NSNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(NSNodeStateEnabled).
|
State(NSNodeStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
Where("clusterId IN (SELECT id FROM "+SharedNSClusterDAO.Table+" WHERE state=1)").
|
Where("clusterId IN (SELECT id FROM "+SharedNSClusterDAO.Table+" WHERE state=1)").
|
||||||
Where("status IS NOT NULL").
|
Where("status IS NOT NULL").
|
||||||
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ossconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
@@ -91,7 +92,8 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
|
|||||||
adminId int64,
|
adminId int64,
|
||||||
userId int64,
|
userId int64,
|
||||||
name string,
|
name string,
|
||||||
addrJSON string,
|
addrJSON []byte,
|
||||||
|
ossConfig *ossconfigs.OSSConfig,
|
||||||
description string,
|
description string,
|
||||||
weight int32, isOn bool,
|
weight int32, isOn bool,
|
||||||
connTimeout *shared.TimeDuration,
|
connTimeout *shared.TimeDuration,
|
||||||
@@ -102,7 +104,8 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
|
|||||||
certRef *sslconfigs.SSLCertRef,
|
certRef *sslconfigs.SSLCertRef,
|
||||||
domains []string,
|
domains []string,
|
||||||
host string,
|
host string,
|
||||||
followPort bool) (originId int64, err error) {
|
followPort bool,
|
||||||
|
http2Enabled bool) (originId int64, err error) {
|
||||||
var op = NewOriginOperator()
|
var op = NewOriginOperator()
|
||||||
op.AdminId = adminId
|
op.AdminId = adminId
|
||||||
op.UserId = userId
|
op.UserId = userId
|
||||||
@@ -141,7 +144,18 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
|
|||||||
op.MaxIdleConns = 0
|
op.MaxIdleConns = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
op.Addr = addrJSON
|
if len(addrJSON) > 0 {
|
||||||
|
op.Addr = addrJSON
|
||||||
|
}
|
||||||
|
|
||||||
|
if ossConfig != nil {
|
||||||
|
ossConfigJSON, err := json.Marshal(ossConfig)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.Oss = ossConfigJSON
|
||||||
|
}
|
||||||
|
|
||||||
op.Description = description
|
op.Description = description
|
||||||
if weight < 0 {
|
if weight < 0 {
|
||||||
weight = 0
|
weight = 0
|
||||||
@@ -169,6 +183,7 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
|
|||||||
|
|
||||||
op.Host = host
|
op.Host = host
|
||||||
op.FollowPort = followPort
|
op.FollowPort = followPort
|
||||||
|
op.Http2Enabled = http2Enabled
|
||||||
|
|
||||||
op.State = OriginStateEnabled
|
op.State = OriginStateEnabled
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
@@ -182,7 +197,8 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx,
|
|||||||
func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
||||||
originId int64,
|
originId int64,
|
||||||
name string,
|
name string,
|
||||||
addrJSON string,
|
addrJSON []byte,
|
||||||
|
ossConfig *ossconfigs.OSSConfig,
|
||||||
description string,
|
description string,
|
||||||
weight int32,
|
weight int32,
|
||||||
isOn bool,
|
isOn bool,
|
||||||
@@ -194,14 +210,25 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
|||||||
certRef *sslconfigs.SSLCertRef,
|
certRef *sslconfigs.SSLCertRef,
|
||||||
domains []string,
|
domains []string,
|
||||||
host string,
|
host string,
|
||||||
followPort bool) error {
|
followPort bool,
|
||||||
|
http2Enabled bool) error {
|
||||||
if originId <= 0 {
|
if originId <= 0 {
|
||||||
return errors.New("invalid originId")
|
return errors.New("invalid originId")
|
||||||
}
|
}
|
||||||
var op = NewOriginOperator()
|
var op = NewOriginOperator()
|
||||||
op.Id = originId
|
op.Id = originId
|
||||||
op.Name = name
|
op.Name = name
|
||||||
|
|
||||||
op.Addr = addrJSON
|
op.Addr = addrJSON
|
||||||
|
|
||||||
|
if ossConfig != nil {
|
||||||
|
ossConfigJSON, err := json.Marshal(ossConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.Oss = ossConfigJSON
|
||||||
|
}
|
||||||
|
|
||||||
op.Description = description
|
op.Description = description
|
||||||
if weight < 0 {
|
if weight < 0 {
|
||||||
weight = 0
|
weight = 0
|
||||||
@@ -266,6 +293,7 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
|||||||
|
|
||||||
op.Host = host
|
op.Host = host
|
||||||
op.FollowPort = followPort
|
op.FollowPort = followPort
|
||||||
|
op.Http2Enabled = http2Enabled
|
||||||
|
|
||||||
err := this.Save(tx, op)
|
err := this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -329,6 +357,7 @@ func (this *OriginDAO) CloneOrigin(tx *dbs.Tx, fromOriginId int64) (newOriginId
|
|||||||
op.Domains = origin.Domains
|
op.Domains = origin.Domains
|
||||||
}
|
}
|
||||||
op.FollowPort = origin.FollowPort
|
op.FollowPort = origin.FollowPort
|
||||||
|
op.Http2Enabled = origin.Http2Enabled
|
||||||
op.State = origin.State
|
op.State = origin.State
|
||||||
return this.SaveInt64(tx, op)
|
return this.SaveInt64(tx, op)
|
||||||
}
|
}
|
||||||
@@ -367,8 +396,10 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap *
|
|||||||
RequestHost: origin.Host,
|
RequestHost: origin.Host,
|
||||||
Domains: origin.DecodeDomains(),
|
Domains: origin.DecodeDomains(),
|
||||||
FollowPort: origin.FollowPort,
|
FollowPort: origin.FollowPort,
|
||||||
|
HTTP2Enabled: origin.Http2Enabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addr
|
||||||
if IsNotNull(origin.Addr) {
|
if IsNotNull(origin.Addr) {
|
||||||
var addr = &serverconfigs.NetworkAddressConfig{}
|
var addr = &serverconfigs.NetworkAddressConfig{}
|
||||||
err = json.Unmarshal(origin.Addr, addr)
|
err = json.Unmarshal(origin.Addr, addr)
|
||||||
@@ -378,6 +409,16 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap *
|
|||||||
config.Addr = addr
|
config.Addr = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// oss
|
||||||
|
if IsNotNull(origin.Oss) {
|
||||||
|
var ossConfig = ossconfigs.NewOSSConfig()
|
||||||
|
err = json.Unmarshal(origin.Oss, ossConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.OSS = ossConfig
|
||||||
|
}
|
||||||
|
|
||||||
if IsNotNull(origin.ConnTimeout) {
|
if IsNotNull(origin.ConnTimeout) {
|
||||||
var connTimeout = &shared.TimeDuration{}
|
var connTimeout = &shared.TimeDuration{}
|
||||||
err = json.Unmarshal(origin.ConnTimeout, &connTimeout)
|
err = json.Unmarshal(origin.ConnTimeout, &connTimeout)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ type Origin struct {
|
|||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Version uint32 `field:"version"` // 版本
|
Version uint32 `field:"version"` // 版本
|
||||||
Addr dbs.JSON `field:"addr"` // 地址
|
Addr dbs.JSON `field:"addr"` // 地址
|
||||||
|
Oss dbs.JSON `field:"oss"` // OSS配置
|
||||||
Description string `field:"description"` // 描述
|
Description string `field:"description"` // 描述
|
||||||
Code string `field:"code"` // 代号
|
Code string `field:"code"` // 代号
|
||||||
Weight uint32 `field:"weight"` // 权重
|
Weight uint32 `field:"weight"` // 权重
|
||||||
@@ -31,36 +32,39 @@ type Origin struct {
|
|||||||
Domains dbs.JSON `field:"domains"` // 所属域名
|
Domains dbs.JSON `field:"domains"` // 所属域名
|
||||||
FollowPort bool `field:"followPort"` // 端口跟随
|
FollowPort bool `field:"followPort"` // 端口跟随
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
|
Http2Enabled bool `field:"http2Enabled"` // 是否支持HTTP/2
|
||||||
}
|
}
|
||||||
|
|
||||||
type OriginOperator struct {
|
type OriginOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
Name interface{} // 名称
|
Name any // 名称
|
||||||
Version interface{} // 版本
|
Version any // 版本
|
||||||
Addr interface{} // 地址
|
Addr any // 地址
|
||||||
Description interface{} // 描述
|
Oss any // OSS配置
|
||||||
Code interface{} // 代号
|
Description any // 描述
|
||||||
Weight interface{} // 权重
|
Code any // 代号
|
||||||
ConnTimeout interface{} // 连接超时
|
Weight any // 权重
|
||||||
ReadTimeout interface{} // 读超时
|
ConnTimeout any // 连接超时
|
||||||
IdleTimeout interface{} // 空闲连接超时
|
ReadTimeout any // 读超时
|
||||||
MaxFails interface{} // 最多失败次数
|
IdleTimeout any // 空闲连接超时
|
||||||
MaxConns interface{} // 最大并发连接数
|
MaxFails any // 最多失败次数
|
||||||
MaxIdleConns interface{} // 最多空闲连接数
|
MaxConns any // 最大并发连接数
|
||||||
HttpRequestURI interface{} // 转发后的请求URI
|
MaxIdleConns any // 最多空闲连接数
|
||||||
HttpRequestHeader interface{} // 请求Header配置
|
HttpRequestURI any // 转发后的请求URI
|
||||||
HttpResponseHeader interface{} // 响应Header配置
|
HttpRequestHeader any // 请求Header配置
|
||||||
Host interface{} // 自定义主机名
|
HttpResponseHeader any // 响应Header配置
|
||||||
HealthCheck interface{} // 健康检查设置
|
Host any // 自定义主机名
|
||||||
Cert interface{} // 证书设置
|
HealthCheck any // 健康检查设置
|
||||||
Ftp interface{} // FTP相关设置
|
Cert any // 证书设置
|
||||||
CreatedAt interface{} // 创建时间
|
Ftp any // FTP相关设置
|
||||||
Domains interface{} // 所属域名
|
CreatedAt any // 创建时间
|
||||||
FollowPort interface{} // 端口跟随
|
Domains any // 所属域名
|
||||||
State interface{} // 状态
|
FollowPort any // 端口跟随
|
||||||
|
State any // 状态
|
||||||
|
Http2Enabled any // 是否支持HTTP/2
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOriginOperator() *OriginOperator {
|
func NewOriginOperator() *OriginOperator {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func init() {
|
|||||||
// EnableRegionCity 启用条目
|
// EnableRegionCity 启用条目
|
||||||
func (this *RegionCityDAO) EnableRegionCity(tx *dbs.Tx, id uint32) error {
|
func (this *RegionCityDAO) EnableRegionCity(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionCityStateEnabled).
|
Set("state", RegionCityStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -51,7 +51,7 @@ func (this *RegionCityDAO) EnableRegionCity(tx *dbs.Tx, id uint32) error {
|
|||||||
// DisableRegionCity 禁用条目
|
// DisableRegionCity 禁用条目
|
||||||
func (this *RegionCityDAO) DisableRegionCity(tx *dbs.Tx, id uint32) error {
|
func (this *RegionCityDAO) DisableRegionCity(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionCityStateDisabled).
|
Set("state", RegionCityStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -60,7 +60,7 @@ func (this *RegionCityDAO) DisableRegionCity(tx *dbs.Tx, id uint32) error {
|
|||||||
// FindEnabledRegionCity 查找启用中的条目
|
// FindEnabledRegionCity 查找启用中的条目
|
||||||
func (this *RegionCityDAO) FindEnabledRegionCity(tx *dbs.Tx, id int64) (*RegionCity, error) {
|
func (this *RegionCityDAO) FindEnabledRegionCity(tx *dbs.Tx, id int64) (*RegionCity, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionCityStateEnabled).
|
Attr("state", RegionCityStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -72,7 +72,7 @@ func (this *RegionCityDAO) FindEnabledRegionCity(tx *dbs.Tx, id int64) (*RegionC
|
|||||||
// FindRegionCityName 根据主键查找名称
|
// FindRegionCityName 根据主键查找名称
|
||||||
func (this *RegionCityDAO) FindRegionCityName(tx *dbs.Tx, id uint32) (string, error) {
|
func (this *RegionCityDAO) FindRegionCityName(tx *dbs.Tx, id uint32) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ func (this *RegionCityDAO) FindRegionCityName(tx *dbs.Tx, id uint32) (string, er
|
|||||||
func (this *RegionCityDAO) FindCityWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
func (this *RegionCityDAO) FindCityWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Attr("dataId", dataId).
|
Attr("dataId", dataId).
|
||||||
ResultPk().
|
Result(RegionCityField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ func (this *RegionCityDAO) CreateCity(tx *dbs.Tx, provinceId int64, name string,
|
|||||||
op.DataId = dataId
|
op.DataId = dataId
|
||||||
op.State = RegionCityStateEnabled
|
op.State = RegionCityStateEnabled
|
||||||
|
|
||||||
codes := []string{name}
|
var codes = []string{name}
|
||||||
codesJSON, err := json.Marshal(codes)
|
codesJSON, err := json.Marshal(codes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -103,7 +103,18 @@ func (this *RegionCityDAO) CreateCity(tx *dbs.Tx, provinceId int64, name string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return types.Int64(op.Id), nil
|
var cityId = types.Int64(op.Id)
|
||||||
|
|
||||||
|
// value id
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(cityId).
|
||||||
|
Set(RegionCityField_ValueId, cityId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return cityId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindCityIdWithName 根据城市名查找城市ID
|
// FindCityIdWithName 根据城市名查找城市ID
|
||||||
@@ -113,7 +124,7 @@ func (this *RegionCityDAO) FindCityIdWithName(tx *dbs.Tx, provinceId int64, city
|
|||||||
Where("(name=:cityName OR customName=:cityName OR JSON_CONTAINS(codes, :cityNameJSON) OR JSON_CONTAINS(customCodes, :cityNameJSON))").
|
Where("(name=:cityName OR customName=:cityName OR JSON_CONTAINS(codes, :cityNameJSON) OR JSON_CONTAINS(customCodes, :cityNameJSON))").
|
||||||
Param("cityName", cityName).
|
Param("cityName", cityName).
|
||||||
Param("cityNameJSON", strconv.Quote(cityName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("cityNameJSON", strconv.Quote(cityName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionCityField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +158,7 @@ func (this *RegionCityDAO) UpdateCityCustom(tx *dbs.Tx, cityId int64, customName
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(cityId).
|
Attr(RegionCityField_ValueId, cityId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
|
|||||||
@@ -2,9 +2,22 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionCityField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionCityField_ValueId dbs.FieldName = "valueId" // 实际ID
|
||||||
|
RegionCityField_ProvinceId dbs.FieldName = "provinceId" // 省份ID
|
||||||
|
RegionCityField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionCityField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionCityField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionCityField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionCityField_State dbs.FieldName = "state" // 状态
|
||||||
|
RegionCityField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
)
|
||||||
|
|
||||||
// RegionCity 区域-城市
|
// RegionCity 区域-城市
|
||||||
type RegionCity struct {
|
type RegionCity struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
ProvinceId uint32 `field:"provinceId"` // 省份ID
|
ProvinceId uint32 `field:"provinceId"` // 省份ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
@@ -15,14 +28,15 @@ type RegionCity struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegionCityOperator struct {
|
type RegionCityOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
ProvinceId interface{} // 省份ID
|
ValueId any // 实际ID
|
||||||
Name interface{} // 名称
|
ProvinceId any // 省份ID
|
||||||
Codes interface{} // 代号
|
Name any // 名称
|
||||||
CustomName interface{} // 自定义名称
|
Codes any // 代号
|
||||||
CustomCodes interface{} // 自定义代号
|
CustomName any // 自定义名称
|
||||||
State interface{} // 状态
|
CustomCodes any // 自定义代号
|
||||||
DataId interface{} // 原始数据ID
|
State any // 状态
|
||||||
|
DataId any // 原始数据ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionCityOperator() *RegionCityOperator {
|
func NewRegionCityOperator() *RegionCityOperator {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/regionconfigs"
|
||||||
_ "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"
|
||||||
@@ -20,10 +21,6 @@ const (
|
|||||||
RegionCountryStateDisabled = 0 // 已禁用
|
RegionCountryStateDisabled = 0 // 已禁用
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
CountryChinaId = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
var regionCountryIdAndNameCacheMap = map[int64]string{} // country id => name
|
var regionCountryIdAndNameCacheMap = map[int64]string{} // country id => name
|
||||||
|
|
||||||
type RegionCountryDAO dbs.DAO
|
type RegionCountryDAO dbs.DAO
|
||||||
@@ -50,7 +47,7 @@ func init() {
|
|||||||
// EnableRegionCountry 启用条目
|
// EnableRegionCountry 启用条目
|
||||||
func (this *RegionCountryDAO) EnableRegionCountry(tx *dbs.Tx, id uint32) error {
|
func (this *RegionCountryDAO) EnableRegionCountry(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionCountryStateEnabled).
|
Set("state", RegionCountryStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -59,7 +56,7 @@ func (this *RegionCountryDAO) EnableRegionCountry(tx *dbs.Tx, id uint32) error {
|
|||||||
// DisableRegionCountry 禁用条目
|
// DisableRegionCountry 禁用条目
|
||||||
func (this *RegionCountryDAO) DisableRegionCountry(tx *dbs.Tx, id int64) error {
|
func (this *RegionCountryDAO) DisableRegionCountry(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionCountryStateDisabled).
|
Set("state", RegionCountryStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -68,7 +65,7 @@ func (this *RegionCountryDAO) DisableRegionCountry(tx *dbs.Tx, id int64) error {
|
|||||||
// FindEnabledRegionCountry 查找启用中的条目
|
// FindEnabledRegionCountry 查找启用中的条目
|
||||||
func (this *RegionCountryDAO) FindEnabledRegionCountry(tx *dbs.Tx, id int64) (*RegionCountry, error) {
|
func (this *RegionCountryDAO) FindEnabledRegionCountry(tx *dbs.Tx, id int64) (*RegionCountry, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionCountryStateEnabled).
|
Attr("state", RegionCountryStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -88,7 +85,7 @@ func (this *RegionCountryDAO) FindRegionCountryName(tx *dbs.Tx, id int64) (strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
name, err := this.Query(tx).
|
name, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,7 +102,7 @@ func (this *RegionCountryDAO) FindRegionCountryName(tx *dbs.Tx, id int64) (strin
|
|||||||
func (this *RegionCountryDAO) FindCountryIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
func (this *RegionCountryDAO) FindCountryIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Attr("dataId", dataId).
|
Attr("dataId", dataId).
|
||||||
ResultPk().
|
Result(RegionCountryField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +112,7 @@ func (this *RegionCountryDAO) FindCountryIdWithName(tx *dbs.Tx, countryName stri
|
|||||||
Where("(name=:countryName OR JSON_CONTAINS(codes, :countryNameJSON) OR customName=:countryName OR JSON_CONTAINS(customCodes, :countryNameJSON))").
|
Where("(name=:countryName OR JSON_CONTAINS(codes, :countryNameJSON) OR customName=:countryName OR JSON_CONTAINS(customCodes, :countryNameJSON))").
|
||||||
Param("countryName", countryName).
|
Param("countryName", countryName).
|
||||||
Param("countryNameJSON", strconv.Quote(countryName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("countryNameJSON", strconv.Quote(countryName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionCountryField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,16 +142,61 @@ func (this *RegionCountryDAO) CreateCountry(tx *dbs.Tx, name string, dataId stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return types.Int64(op.Id), nil
|
var countryId = types.Int64(op.Id)
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(countryId).
|
||||||
|
Set(RegionCountryField_ValueId, countryId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return countryId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledCountriesOrderByPinyin 查找所有可用的国家并按拼音排序
|
// FindAllEnabledCountriesOrderByPinyin 查找所有可用的国家并按拼音排序
|
||||||
func (this *RegionCountryDAO) FindAllEnabledCountriesOrderByPinyin(tx *dbs.Tx) (result []*RegionCountry, err error) {
|
func (this *RegionCountryDAO) FindAllEnabledCountriesOrderByPinyin(tx *dbs.Tx) (result []*RegionCountry, err error) {
|
||||||
_, err = this.Query(tx).
|
ones, err := this.Query(tx).
|
||||||
State(RegionCountryStateEnabled).
|
State(RegionCountryStateEnabled).
|
||||||
Slice(&result).
|
Asc("JSON_EXTRACT(pinyin, '$[0]')").
|
||||||
Asc("pinyin").
|
|
||||||
FindAll()
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// resort China special regions
|
||||||
|
var chinaRegionMap = map[int64]*RegionCountry{} // countryId => *RegionCountry
|
||||||
|
for _, one := range ones {
|
||||||
|
var country = one.(*RegionCountry)
|
||||||
|
var valueId = int64(country.ValueId)
|
||||||
|
if regionconfigs.CheckRegionIsInGreaterChina(valueId) {
|
||||||
|
chinaRegionMap[valueId] = country
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, one := range ones {
|
||||||
|
var country = one.(*RegionCountry)
|
||||||
|
var valueId = int64(country.ValueId)
|
||||||
|
if valueId == regionconfigs.RegionChinaId {
|
||||||
|
result = append(result, country)
|
||||||
|
|
||||||
|
// add hk, tw, mo, mainland ...
|
||||||
|
for _, subRegionId := range regionconfigs.FindAllGreaterChinaSubRegionIds() {
|
||||||
|
subRegion, ok := chinaRegionMap[subRegionId]
|
||||||
|
if ok {
|
||||||
|
result = append(result, subRegion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if regionconfigs.CheckRegionIsInGreaterChina(valueId) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, country)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +205,7 @@ func (this *RegionCountryDAO) FindAllCountries(tx *dbs.Tx) (result []*RegionCoun
|
|||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionCountryStateEnabled).
|
State(RegionCountryStateEnabled).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
AscPk().
|
Asc(RegionCountryField_ValueId).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -185,7 +227,7 @@ func (this *RegionCountryDAO) UpdateCountryCustom(tx *dbs.Tx, countryId int64, c
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(countryId).
|
Attr("valueId", countryId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
|
|||||||
@@ -2,9 +2,25 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionCountryField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionCountryField_ValueId dbs.FieldName = "valueId" // 实际ID
|
||||||
|
RegionCountryField_ValueCode dbs.FieldName = "valueCode" // 值代号
|
||||||
|
RegionCountryField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionCountryField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionCountryField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionCountryField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionCountryField_State dbs.FieldName = "state" // 状态
|
||||||
|
RegionCountryField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
RegionCountryField_Pinyin dbs.FieldName = "pinyin" // 拼音
|
||||||
|
RegionCountryField_IsCommon dbs.FieldName = "isCommon" // 是否常用
|
||||||
|
)
|
||||||
|
|
||||||
// RegionCountry 区域-国家/地区
|
// RegionCountry 区域-国家/地区
|
||||||
type RegionCountry struct {
|
type RegionCountry struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
|
ValueCode string `field:"valueCode"` // 值代号
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
CustomName string `field:"customName"` // 自定义名称
|
CustomName string `field:"customName"` // 自定义名称
|
||||||
@@ -12,17 +28,21 @@ type RegionCountry struct {
|
|||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
DataId string `field:"dataId"` // 原始数据ID
|
DataId string `field:"dataId"` // 原始数据ID
|
||||||
Pinyin dbs.JSON `field:"pinyin"` // 拼音
|
Pinyin dbs.JSON `field:"pinyin"` // 拼音
|
||||||
|
IsCommon bool `field:"isCommon"` // 是否常用
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegionCountryOperator struct {
|
type RegionCountryOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
Name interface{} // 名称
|
ValueId any // 实际ID
|
||||||
Codes interface{} // 代号
|
ValueCode any // 值代号
|
||||||
CustomName interface{} // 自定义名称
|
Name any // 名称
|
||||||
CustomCodes interface{} // 自定义代号
|
Codes any // 代号
|
||||||
State interface{} // 状态
|
CustomName any // 自定义名称
|
||||||
DataId interface{} // 原始数据ID
|
CustomCodes any // 自定义代号
|
||||||
Pinyin interface{} // 拼音
|
State any // 状态
|
||||||
|
DataId any // 原始数据ID
|
||||||
|
Pinyin any // 拼音
|
||||||
|
IsCommon any // 是否常用
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionCountryOperator() *RegionCountryOperator {
|
func NewRegionCountryOperator() *RegionCountryOperator {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func init() {
|
|||||||
// EnableRegionProvider 启用条目
|
// EnableRegionProvider 启用条目
|
||||||
func (this *RegionProviderDAO) EnableRegionProvider(tx *dbs.Tx, id uint32) error {
|
func (this *RegionProviderDAO) EnableRegionProvider(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionProviderStateEnabled).
|
Set("state", RegionProviderStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -50,7 +50,7 @@ func (this *RegionProviderDAO) EnableRegionProvider(tx *dbs.Tx, id uint32) error
|
|||||||
// DisableRegionProvider 禁用条目
|
// DisableRegionProvider 禁用条目
|
||||||
func (this *RegionProviderDAO) DisableRegionProvider(tx *dbs.Tx, id uint32) error {
|
func (this *RegionProviderDAO) DisableRegionProvider(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionProviderStateDisabled).
|
Set("state", RegionProviderStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -59,7 +59,7 @@ func (this *RegionProviderDAO) DisableRegionProvider(tx *dbs.Tx, id uint32) erro
|
|||||||
// FindEnabledRegionProvider 查找启用中的条目
|
// FindEnabledRegionProvider 查找启用中的条目
|
||||||
func (this *RegionProviderDAO) FindEnabledRegionProvider(tx *dbs.Tx, id int64) (*RegionProvider, error) {
|
func (this *RegionProviderDAO) FindEnabledRegionProvider(tx *dbs.Tx, id int64) (*RegionProvider, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionProviderStateEnabled).
|
Attr("state", RegionProviderStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -71,7 +71,7 @@ func (this *RegionProviderDAO) FindEnabledRegionProvider(tx *dbs.Tx, id int64) (
|
|||||||
// FindRegionProviderName 根据主键查找名称
|
// FindRegionProviderName 根据主键查找名称
|
||||||
func (this *RegionProviderDAO) FindRegionProviderName(tx *dbs.Tx, id uint32) (string, error) {
|
func (this *RegionProviderDAO) FindRegionProviderName(tx *dbs.Tx, id uint32) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ func (this *RegionProviderDAO) FindProviderIdWithName(tx *dbs.Tx, providerName s
|
|||||||
Where("(name=:providerName OR customName=:providerName OR JSON_CONTAINS(codes, :providerNameJSON) OR JSON_CONTAINS(customCodes, :providerNameJSON))").
|
Where("(name=:providerName OR customName=:providerName OR JSON_CONTAINS(codes, :providerNameJSON) OR JSON_CONTAINS(customCodes, :providerNameJSON))").
|
||||||
Param("providerName", providerName).
|
Param("providerName", providerName).
|
||||||
Param("providerNameJSON", strconv.Quote(providerName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("providerNameJSON", strconv.Quote(providerName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionProviderField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,20 @@ func (this *RegionProviderDAO) CreateProvider(tx *dbs.Tx, name string) (int64, e
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
op.Codes = codesJSON
|
op.Codes = codesJSON
|
||||||
return this.SaveInt64(tx, op)
|
providerId, err := this.SaveInt64(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(providerId).
|
||||||
|
Set(RegionProviderField_ValueId, providerId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return providerId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledProviders 查找所有服务商
|
// FindAllEnabledProviders 查找所有服务商
|
||||||
@@ -119,7 +132,7 @@ func (this *RegionProviderDAO) UpdateProviderCustom(tx *dbs.Tx, providerId int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(providerId).
|
Attr("valueId", providerId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
|
|||||||
@@ -2,9 +2,20 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionProviderField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionProviderField_ValueId dbs.FieldName = "valueId" // 实际ID
|
||||||
|
RegionProviderField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionProviderField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionProviderField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionProviderField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionProviderField_State dbs.FieldName = "state" // 状态
|
||||||
|
)
|
||||||
|
|
||||||
// RegionProvider 区域-运营商
|
// RegionProvider 区域-运营商
|
||||||
type RegionProvider struct {
|
type RegionProvider struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
CustomName string `field:"customName"` // 自定义名称
|
CustomName string `field:"customName"` // 自定义名称
|
||||||
@@ -13,12 +24,13 @@ type RegionProvider struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegionProviderOperator struct {
|
type RegionProviderOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
Name interface{} // 名称
|
ValueId any // 实际ID
|
||||||
Codes interface{} // 代号
|
Name any // 名称
|
||||||
CustomName interface{} // 自定义名称
|
Codes any // 代号
|
||||||
CustomCodes interface{} // 自定义代号
|
CustomName any // 自定义名称
|
||||||
State interface{} // 状态
|
CustomCodes any // 自定义代号
|
||||||
|
State any // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionProviderOperator() *RegionProviderOperator {
|
func NewRegionProviderOperator() *RegionProviderOperator {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func init() {
|
|||||||
// EnableRegionProvince 启用条目
|
// EnableRegionProvince 启用条目
|
||||||
func (this *RegionProvinceDAO) EnableRegionProvince(tx *dbs.Tx, id int64) error {
|
func (this *RegionProvinceDAO) EnableRegionProvince(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionProvinceStateEnabled).
|
Set("state", RegionProvinceStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -51,7 +51,7 @@ func (this *RegionProvinceDAO) EnableRegionProvince(tx *dbs.Tx, id int64) error
|
|||||||
// DisableRegionProvince 禁用条目
|
// DisableRegionProvince 禁用条目
|
||||||
func (this *RegionProvinceDAO) DisableRegionProvince(tx *dbs.Tx, id int64) error {
|
func (this *RegionProvinceDAO) DisableRegionProvince(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionProvinceStateDisabled).
|
Set("state", RegionProvinceStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -60,7 +60,7 @@ func (this *RegionProvinceDAO) DisableRegionProvince(tx *dbs.Tx, id int64) error
|
|||||||
// FindEnabledRegionProvince 查找启用中的条目
|
// FindEnabledRegionProvince 查找启用中的条目
|
||||||
func (this *RegionProvinceDAO) FindEnabledRegionProvince(tx *dbs.Tx, id int64) (*RegionProvince, error) {
|
func (this *RegionProvinceDAO) FindEnabledRegionProvince(tx *dbs.Tx, id int64) (*RegionProvince, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionProvinceStateEnabled).
|
Attr("state", RegionProvinceStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -72,7 +72,7 @@ func (this *RegionProvinceDAO) FindEnabledRegionProvince(tx *dbs.Tx, id int64) (
|
|||||||
// FindRegionProvinceName 根据主键查找名称
|
// FindRegionProvinceName 根据主键查找名称
|
||||||
func (this *RegionProvinceDAO) FindRegionProvinceName(tx *dbs.Tx, id int64) (string, error) {
|
func (this *RegionProvinceDAO) FindRegionProvinceName(tx *dbs.Tx, id int64) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ func (this *RegionProvinceDAO) FindRegionProvinceName(tx *dbs.Tx, id int64) (str
|
|||||||
func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
func (this *RegionProvinceDAO) FindProvinceIdWithDataId(tx *dbs.Tx, dataId string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Attr("dataId", dataId).
|
Attr("dataId", dataId).
|
||||||
ResultPk().
|
Result(RegionProvinceField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ func (this *RegionProvinceDAO) FindProvinceIdWithName(tx *dbs.Tx, countryId int6
|
|||||||
Where("(name=:provinceName OR customName=:provinceName OR JSON_CONTAINS(codes, :provinceNameJSON) OR JSON_CONTAINS(customCodes, :provinceNameJSON))").
|
Where("(name=:provinceName OR customName=:provinceName OR JSON_CONTAINS(codes, :provinceNameJSON) OR JSON_CONTAINS(customCodes, :provinceNameJSON))").
|
||||||
Param("provinceName", provinceName).
|
Param("provinceName", provinceName).
|
||||||
Param("provinceNameJSON", strconv.Quote(provinceName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("provinceNameJSON", strconv.Quote(provinceName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionProvinceField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ func (this *RegionProvinceDAO) CreateProvince(tx *dbs.Tx, countryId int64, name
|
|||||||
op.DataId = dataId
|
op.DataId = dataId
|
||||||
op.State = RegionProvinceStateEnabled
|
op.State = RegionProvinceStateEnabled
|
||||||
|
|
||||||
codes := []string{name}
|
var codes = []string{name}
|
||||||
codesJSON, err := json.Marshal(codes)
|
codesJSON, err := json.Marshal(codes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -114,7 +114,17 @@ func (this *RegionProvinceDAO) CreateProvince(tx *dbs.Tx, countryId int64, name
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return types.Int64(op.Id), nil
|
var provinceId = types.Int64(op.Id)
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(provinceId).
|
||||||
|
Set(RegionProvinceField_ValueId, provinceId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return provinceId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledProvincesWithCountryId 查找某个国家/地区的所有省份
|
// FindAllEnabledProvincesWithCountryId 查找某个国家/地区的所有省份
|
||||||
@@ -122,7 +132,7 @@ func (this *RegionProvinceDAO) FindAllEnabledProvincesWithCountryId(tx *dbs.Tx,
|
|||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionProvinceStateEnabled).
|
State(RegionProvinceStateEnabled).
|
||||||
Attr("countryId", countryId).
|
Attr("countryId", countryId).
|
||||||
AscPk().
|
Asc(RegionProvinceField_ValueId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
@@ -132,7 +142,7 @@ func (this *RegionProvinceDAO) FindAllEnabledProvincesWithCountryId(tx *dbs.Tx,
|
|||||||
func (this *RegionProvinceDAO) FindAllEnabledProvinces(tx *dbs.Tx) (result []*RegionProvince, err error) {
|
func (this *RegionProvinceDAO) FindAllEnabledProvinces(tx *dbs.Tx) (result []*RegionProvince, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionProvinceStateEnabled).
|
State(RegionProvinceStateEnabled).
|
||||||
AscPk().
|
Asc(RegionProvinceField_ValueId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
@@ -149,7 +159,7 @@ func (this *RegionProvinceDAO) UpdateProvinceCustom(tx *dbs.Tx, provinceId int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(provinceId).
|
Attr("valueId", provinceId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
|
|||||||
@@ -2,9 +2,22 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionProvinceField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionProvinceField_ValueId dbs.FieldName = "valueId" // 实际ID
|
||||||
|
RegionProvinceField_CountryId dbs.FieldName = "countryId" // 国家ID
|
||||||
|
RegionProvinceField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionProvinceField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionProvinceField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionProvinceField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionProvinceField_State dbs.FieldName = "state" // 状态
|
||||||
|
RegionProvinceField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
)
|
||||||
|
|
||||||
// RegionProvince 区域-省份
|
// RegionProvince 区域-省份
|
||||||
type RegionProvince struct {
|
type RegionProvince struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 实际ID
|
||||||
CountryId uint32 `field:"countryId"` // 国家ID
|
CountryId uint32 `field:"countryId"` // 国家ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
@@ -15,14 +28,15 @@ type RegionProvince struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegionProvinceOperator struct {
|
type RegionProvinceOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
CountryId interface{} // 国家ID
|
ValueId any // 实际ID
|
||||||
Name interface{} // 名称
|
CountryId any // 国家ID
|
||||||
Codes interface{} // 代号
|
Name any // 名称
|
||||||
CustomName interface{} // 自定义名称
|
Codes any // 代号
|
||||||
CustomCodes interface{} // 自定义代号
|
CustomName any // 自定义名称
|
||||||
State interface{} // 状态
|
CustomCodes any // 自定义代号
|
||||||
DataId interface{} // 原始数据ID
|
State any // 状态
|
||||||
|
DataId any // 原始数据ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionProvinceOperator() *RegionProvinceOperator {
|
func NewRegionProvinceOperator() *RegionProvinceOperator {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func init() {
|
|||||||
// EnableRegionTown 启用条目
|
// EnableRegionTown 启用条目
|
||||||
func (this *RegionTownDAO) EnableRegionTown(tx *dbs.Tx, id uint32) error {
|
func (this *RegionTownDAO) EnableRegionTown(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionTownStateEnabled).
|
Set("state", RegionTownStateEnabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -50,7 +50,7 @@ func (this *RegionTownDAO) EnableRegionTown(tx *dbs.Tx, id uint32) error {
|
|||||||
// DisableRegionTown 禁用条目
|
// DisableRegionTown 禁用条目
|
||||||
func (this *RegionTownDAO) DisableRegionTown(tx *dbs.Tx, id uint32) error {
|
func (this *RegionTownDAO) DisableRegionTown(tx *dbs.Tx, id uint32) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Set("state", RegionTownStateDisabled).
|
Set("state", RegionTownStateDisabled).
|
||||||
Update()
|
Update()
|
||||||
return err
|
return err
|
||||||
@@ -59,7 +59,7 @@ func (this *RegionTownDAO) DisableRegionTown(tx *dbs.Tx, id uint32) error {
|
|||||||
// FindEnabledRegionTown 查找启用中的区县
|
// FindEnabledRegionTown 查找启用中的区县
|
||||||
func (this *RegionTownDAO) FindEnabledRegionTown(tx *dbs.Tx, id int64) (*RegionTown, error) {
|
func (this *RegionTownDAO) FindEnabledRegionTown(tx *dbs.Tx, id int64) (*RegionTown, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Attr("state", RegionTownStateEnabled).
|
Attr("state", RegionTownStateEnabled).
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
@@ -72,7 +72,7 @@ func (this *RegionTownDAO) FindEnabledRegionTown(tx *dbs.Tx, id int64) (*RegionT
|
|||||||
func (this *RegionTownDAO) FindAllRegionTowns(tx *dbs.Tx) (result []*RegionTown, err error) {
|
func (this *RegionTownDAO) FindAllRegionTowns(tx *dbs.Tx) (result []*RegionTown, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionTownStateEnabled).
|
State(RegionTownStateEnabled).
|
||||||
AscPk().
|
Asc(RegionTownField_ValueId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
@@ -83,7 +83,7 @@ func (this *RegionTownDAO) FindAllRegionTownsWithCityId(tx *dbs.Tx, cityId int64
|
|||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(RegionTownStateEnabled).
|
State(RegionTownStateEnabled).
|
||||||
Attr("cityId", cityId).
|
Attr("cityId", cityId).
|
||||||
AscPk().
|
Asc(RegionTownField_ValueId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
@@ -96,14 +96,14 @@ func (this *RegionTownDAO) FindTownIdWithName(tx *dbs.Tx, cityId int64, townName
|
|||||||
Where("(name=:townName OR customName=:townName OR JSON_CONTAINS(codes, :townNameJSON) OR JSON_CONTAINS(customCodes, :townNameJSON))").
|
Where("(name=:townName OR customName=:townName OR JSON_CONTAINS(codes, :townNameJSON) OR JSON_CONTAINS(customCodes, :townNameJSON))").
|
||||||
Param("townName", townName).
|
Param("townName", townName).
|
||||||
Param("townNameJSON", strconv.Quote(townName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
Param("townNameJSON", strconv.Quote(townName)). // 查询的需要是个JSON字符串,所以这里加双引号
|
||||||
ResultPk().
|
Result(RegionTownField_ValueId).
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindRegionTownName 根据主键查找名称
|
// FindRegionTownName 根据主键查找名称
|
||||||
func (this *RegionTownDAO) FindRegionTownName(tx *dbs.Tx, id uint32) (string, error) {
|
func (this *RegionTownDAO) FindRegionTownName(tx *dbs.Tx, id uint32) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Attr("valueId", id).
|
||||||
Result("name").
|
Result("name").
|
||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ func (this *RegionTownDAO) UpdateTownCustom(tx *dbs.Tx, townId int64, customName
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(townId).
|
Attr("valueId", townId).
|
||||||
Set("customName", customName).
|
Set("customName", customName).
|
||||||
Set("customCodes", customCodesJSON).
|
Set("customCodes", customCodesJSON).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
@@ -176,5 +176,18 @@ func (this *RegionTownDAO) CreateTown(tx *dbs.Tx, cityId int64, townName string)
|
|||||||
op.Codes = codes
|
op.Codes = codes
|
||||||
|
|
||||||
op.State = RegionTownStateEnabled
|
op.State = RegionTownStateEnabled
|
||||||
return this.SaveInt64(tx, op)
|
townId, err := this.SaveInt64(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(townId).
|
||||||
|
Set(RegionTownField_ValueId, townId).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return townId, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,22 @@ package regions
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegionTownField_Id dbs.FieldName = "id" // ID
|
||||||
|
RegionTownField_ValueId dbs.FieldName = "valueId" // 真实ID
|
||||||
|
RegionTownField_CityId dbs.FieldName = "cityId" // 城市ID
|
||||||
|
RegionTownField_Name dbs.FieldName = "name" // 名称
|
||||||
|
RegionTownField_Codes dbs.FieldName = "codes" // 代号
|
||||||
|
RegionTownField_CustomName dbs.FieldName = "customName" // 自定义名称
|
||||||
|
RegionTownField_CustomCodes dbs.FieldName = "customCodes" // 自定义代号
|
||||||
|
RegionTownField_State dbs.FieldName = "state" // 状态
|
||||||
|
RegionTownField_DataId dbs.FieldName = "dataId" // 原始数据ID
|
||||||
|
)
|
||||||
|
|
||||||
// RegionTown 区域-省份
|
// RegionTown 区域-省份
|
||||||
type RegionTown struct {
|
type RegionTown struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id1 uint32 `field:"id"` // ID
|
||||||
|
ValueId uint32 `field:"valueId"` // 真实ID
|
||||||
CityId uint32 `field:"cityId"` // 城市ID
|
CityId uint32 `field:"cityId"` // 城市ID
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Codes dbs.JSON `field:"codes"` // 代号
|
Codes dbs.JSON `field:"codes"` // 代号
|
||||||
@@ -15,14 +28,15 @@ type RegionTown struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegionTownOperator struct {
|
type RegionTownOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
CityId interface{} // 城市ID
|
ValueId any // 真实ID
|
||||||
Name interface{} // 名称
|
CityId any // 城市ID
|
||||||
Codes interface{} // 代号
|
Name any // 名称
|
||||||
CustomName interface{} // 自定义名称
|
Codes any // 代号
|
||||||
CustomCodes interface{} // 自定义代号
|
CustomName any // 自定义名称
|
||||||
State interface{} // 状态
|
CustomCodes any // 自定义代号
|
||||||
DataId interface{} // 原始数据ID
|
State any // 状态
|
||||||
|
DataId any // 原始数据ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRegionTownOperator() *RegionTownOperator {
|
func NewRegionTownOperator() *RegionTownOperator {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedServerBandwidthStatDAO.Clean(nil)
|
err := SharedServerBandwidthStatDAO.CleanDefaultDays(nil, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("SharedServerBandwidthStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("SharedServerBandwidthStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -745,9 +745,9 @@ func (this *ServerBandwidthStatDAO) SumDailyStat(tx *dbs.Tx, serverId int64, reg
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理过期数据
|
// CleanDays 清理过期数据
|
||||||
func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
func (this *ServerBandwidthStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days)) // 保留大约3个月的数据
|
||||||
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Table(table).
|
Table(table).
|
||||||
@@ -757,6 +757,22 @@ func (this *ServerBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *ServerBandwidthStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.ServerBandwidthStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.ServerBandwidthStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|
||||||
// 批量执行
|
// 批量执行
|
||||||
func (this *ServerBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
func (this *ServerBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
||||||
var locker = &sync.Mutex{}
|
var locker = &sync.Mutex{}
|
||||||
|
|||||||
@@ -72,11 +72,11 @@ func TestServerBandwidthStatDAO_FindAllServerStatsWithDay(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerBandwidthStatDAO_Clean(t *testing.T) {
|
func TestServerBandwidthStatDAO_CleanDays(t *testing.T) {
|
||||||
var dao = models.NewServerBandwidthStatDAO()
|
var dao = models.NewServerBandwidthStatDAO()
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
var before = time.Now()
|
var before = time.Now()
|
||||||
err := dao.Clean(tx)
|
err := dao.CleanDays(tx, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,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"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -28,7 +29,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedServerDailyStatDAO.Clean(nil, 60) // 只保留 N 天,时间需要长一些,因为需要用来生成账单
|
err := SharedServerDailyStatDAO.CleanDefaultDays(nil, 60) // 只保留 N 天,时间需要长一些,因为需要用来生成账单
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Println("ServerDailyStatDAO", "clean expired data failed: "+err.Error())
|
logs.Println("ServerDailyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -513,7 +514,8 @@ func (this *ServerDailyStatDAO) FindStatsWithDay(tx *dbs.Tx, serverId int64, day
|
|||||||
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "day", "timeFrom", "MIN(timeTo) AS timeTo").
|
Result("SUM(bytes) AS bytes", "SUM(cachedBytes) AS cachedBytes", "SUM(countRequests) AS countRequests", "SUM(countCachedRequests) AS countCachedRequests", "SUM(countAttackRequests) AS countAttackRequests", "SUM(attackBytes) AS attackBytes", "day", "timeFrom", "MIN(timeTo) AS timeTo").
|
||||||
Attr("serverId", serverId).
|
Attr("serverId", serverId).
|
||||||
Attr("day", day).
|
Attr("day", day).
|
||||||
Group("day").Group("timeFrom", dbs.QueryOrderDesc)
|
Group("day").
|
||||||
|
Group("timeFrom")
|
||||||
|
|
||||||
if len(timeFrom) > 0 {
|
if len(timeFrom) > 0 {
|
||||||
query.Gte("timeFrom", timeFrom)
|
query.Gte("timeFrom", timeFrom)
|
||||||
@@ -530,6 +532,11 @@ func (this *ServerDailyStatDAO) FindStatsWithDay(tx *dbs.Tx, serverId int64, day
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort results
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].TimeFrom < result[j].TimeFrom
|
||||||
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,8 +680,8 @@ func (this *ServerDailyStatDAO) compatFindHourlyStats(tx *dbs.Tx, serverId int64
|
|||||||
result = append(result, stat)
|
result = append(result, stat)
|
||||||
} else {
|
} else {
|
||||||
result = append(result, &ServerDailyStat{
|
result = append(result, &ServerDailyStat{
|
||||||
Hour: hour,
|
Hour: hour,
|
||||||
Day: hour[:8],
|
Day: hour[:8],
|
||||||
TimeFrom: hour[8:] + "00",
|
TimeFrom: hour[8:] + "00",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -742,11 +749,27 @@ func (this *ServerDailyStatDAO) UpdateStatFee(tx *dbs.Tx, statId int64, fee floa
|
|||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *ServerDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *ServerDailyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("day", day).
|
Lt("day", day).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *ServerDailyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.ServerDailyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.ServerDailyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 60
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -140,6 +140,6 @@ func TestServerDailyStatDAO_FindStatsWithDay(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, stat := range stats {
|
for _, stat := range stats {
|
||||||
t.Log(stat.TimeFrom, stat.TimeTo, stat.Bytes)
|
t.Log(stat.Day, stat.TimeFrom, stat.TimeTo, stat.Bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,6 +354,9 @@ func (this *ServerDAO) UpdateServerBasic(tx *dbs.Tx, serverId int64, name string
|
|||||||
|
|
||||||
// UpdateServerGroupIds 修改服务所在分组
|
// UpdateServerGroupIds 修改服务所在分组
|
||||||
func (this *ServerDAO) UpdateServerGroupIds(tx *dbs.Tx, serverId int64, groupIds []int64) error {
|
func (this *ServerDAO) UpdateServerGroupIds(tx *dbs.Tx, serverId int64, groupIds []int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return errors.New("serverId should not be smaller than 0")
|
||||||
|
}
|
||||||
if groupIds == nil {
|
if groupIds == nil {
|
||||||
groupIds = []int64{}
|
groupIds = []int64{}
|
||||||
}
|
}
|
||||||
@@ -390,6 +393,10 @@ func (this *ServerDAO) UpdateUserServerBasic(tx *dbs.Tx, serverId int64, name st
|
|||||||
|
|
||||||
// UpdateServerIsOn 修复服务是否启用
|
// UpdateServerIsOn 修复服务是否启用
|
||||||
func (this *ServerDAO) UpdateServerIsOn(tx *dbs.Tx, serverId int64, isOn bool) error {
|
func (this *ServerDAO) UpdateServerIsOn(tx *dbs.Tx, serverId int64, isOn bool) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return errors.New("serverId should not be smaller than 0")
|
||||||
|
}
|
||||||
|
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Set("isOn", isOn).
|
Set("isOn", isOn).
|
||||||
@@ -896,6 +903,22 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
|
|||||||
query.Desc("IF(FIND_IN_SET(bandwidthTime, :times), bandwidthBytes, 0)")
|
query.Desc("IF(FIND_IN_SET(bandwidthTime, :times), bandwidthBytes, 0)")
|
||||||
query.Param("times", strings.Join(times, ","))
|
query.Param("times", strings.Join(times, ","))
|
||||||
query.DescPk()
|
query.DescPk()
|
||||||
|
case "requestsAsc":
|
||||||
|
query.Asc("IF(FIND_IN_SET(bandwidthTime, :times), countRequests, 0)")
|
||||||
|
query.Param("times", strings.Join(times, ","))
|
||||||
|
query.DescPk()
|
||||||
|
case "requestsDesc":
|
||||||
|
query.Desc("IF(FIND_IN_SET(bandwidthTime, :times), countRequests, 0)")
|
||||||
|
query.Param("times", strings.Join(times, ","))
|
||||||
|
query.DescPk()
|
||||||
|
case "attackRequestsAsc":
|
||||||
|
query.Asc("IF(FIND_IN_SET(bandwidthTime, :times), countAttackRequests, 0)")
|
||||||
|
query.Param("times", strings.Join(times, ","))
|
||||||
|
query.DescPk()
|
||||||
|
case "attackRequestsDesc":
|
||||||
|
query.Desc("IF(FIND_IN_SET(bandwidthTime, :times), countAttackRequests, 0)")
|
||||||
|
query.Param("times", strings.Join(times, ","))
|
||||||
|
query.DescPk()
|
||||||
default:
|
default:
|
||||||
query.DescPk()
|
query.DescPk()
|
||||||
}
|
}
|
||||||
@@ -906,6 +929,8 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
|
|||||||
for _, server := range result {
|
for _, server := range result {
|
||||||
if len(server.BandwidthTime) > 0 && !lists.ContainsString(times, server.BandwidthTime) {
|
if len(server.BandwidthTime) > 0 && !lists.ContainsString(times, server.BandwidthTime) {
|
||||||
server.BandwidthBytes = 0
|
server.BandwidthBytes = 0
|
||||||
|
server.CountRequests = 0
|
||||||
|
server.CountAttackRequests = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2153,6 +2178,10 @@ func (this *ServerDAO) FindFirstHTTPOrHTTPSPortWithClusterId(tx *dbs.Tx, cluster
|
|||||||
|
|
||||||
// NotifyServerPortsUpdate 通知服务端口变化
|
// NotifyServerPortsUpdate 通知服务端口变化
|
||||||
func (this *ServerDAO) NotifyServerPortsUpdate(tx *dbs.Tx, serverId int64) error {
|
func (this *ServerDAO) NotifyServerPortsUpdate(tx *dbs.Tx, serverId int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
one, err := this.Query(tx).
|
one, err := this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Result("tcp", "tls", "udp", "http", "https").
|
Result("tcp", "tls", "udp", "http", "https").
|
||||||
@@ -2480,6 +2509,10 @@ func (this *ServerDAO) UpdateServerTrafficLimitStatus(tx *dbs.Tx, trafficLimitCo
|
|||||||
|
|
||||||
// IncreaseServerTotalTraffic 增加服务的总流量
|
// IncreaseServerTotalTraffic 增加服务的总流量
|
||||||
func (this *ServerDAO) IncreaseServerTotalTraffic(tx *dbs.Tx, serverId int64, bytes int64) error {
|
func (this *ServerDAO) IncreaseServerTotalTraffic(tx *dbs.Tx, serverId int64, bytes int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return errors.New("serverId should not be smaller than 0")
|
||||||
|
}
|
||||||
|
|
||||||
var gb = float64(bytes) / (1 << 30)
|
var gb = float64(bytes) / (1 << 30)
|
||||||
var day = timeutil.Format("Ymd")
|
var day = timeutil.Format("Ymd")
|
||||||
var month = timeutil.Format("Ym")
|
var month = timeutil.Format("Ym")
|
||||||
@@ -2539,6 +2572,10 @@ func (this *ServerDAO) UpdateServersClusterIdWithPlanId(tx *dbs.Tx, planId int64
|
|||||||
|
|
||||||
// UpdateServerUserPlanId 设置服务所属套餐
|
// UpdateServerUserPlanId 设置服务所属套餐
|
||||||
func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPlanId int64) error {
|
func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPlanId int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return errors.New("serverId should not be smaller than 0")
|
||||||
|
}
|
||||||
|
|
||||||
oldClusterId, err := this.Query(tx).
|
oldClusterId, err := this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Result("clusterId").
|
Result("clusterId").
|
||||||
@@ -2646,6 +2683,10 @@ func (this *ServerDAO) UpdateServerUserPlanId(tx *dbs.Tx, serverId int64, userPl
|
|||||||
|
|
||||||
// FindServerLastUserPlanIdAndUserId 查找最后使用的套餐
|
// FindServerLastUserPlanIdAndUserId 查找最后使用的套餐
|
||||||
func (this *ServerDAO) FindServerLastUserPlanIdAndUserId(tx *dbs.Tx, serverId int64) (userPlanId int64, userId int64, err error) {
|
func (this *ServerDAO) FindServerLastUserPlanIdAndUserId(tx *dbs.Tx, serverId int64) (userPlanId int64, userId int64, err error) {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return 0, 0, errors.New("serverId should not be smaller than 0")
|
||||||
|
}
|
||||||
|
|
||||||
one, err := this.Query(tx).
|
one, err := this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Result("lastUserPlanId", "userId").
|
Result("lastUserPlanId", "userId").
|
||||||
@@ -2659,6 +2700,10 @@ func (this *ServerDAO) FindServerLastUserPlanIdAndUserId(tx *dbs.Tx, serverId in
|
|||||||
|
|
||||||
// UpdateServerUAM 开启UAM
|
// UpdateServerUAM 开启UAM
|
||||||
func (this *ServerDAO) UpdateServerUAM(tx *dbs.Tx, serverId int64, uamConfig *serverconfigs.UAMConfig) error {
|
func (this *ServerDAO) UpdateServerUAM(tx *dbs.Tx, serverId int64, uamConfig *serverconfigs.UAMConfig) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return errors.New("serverId should not be smaller than 0")
|
||||||
|
}
|
||||||
|
|
||||||
if uamConfig == nil {
|
if uamConfig == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -2710,7 +2755,7 @@ func (this *ServerDAO) FindUserServerClusterIds(tx *dbs.Tx, userId int64) ([]int
|
|||||||
|
|
||||||
// UpdateServerBandwidth 更新服务带宽
|
// UpdateServerBandwidth 更新服务带宽
|
||||||
// fullTime YYYYMMDDHHII
|
// fullTime YYYYMMDDHHII
|
||||||
func (this *ServerDAO) UpdateServerBandwidth(tx *dbs.Tx, serverId int64, fullTime string, bandwidthBytes int64) error {
|
func (this *ServerDAO) UpdateServerBandwidth(tx *dbs.Tx, serverId int64, fullTime string, bandwidthBytes int64, countRequests int64, countAttackRequests int64) error {
|
||||||
if serverId <= 0 {
|
if serverId <= 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -2731,13 +2776,19 @@ func (this *ServerDAO) UpdateServerBandwidth(tx *dbs.Tx, serverId int64, fullTim
|
|||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Set("bandwidthTime", fullTime).
|
Set("bandwidthTime", fullTime).
|
||||||
Set("bandwidthBytes", bandwidthBytes).
|
Set("bandwidthBytes", bandwidthBytes).
|
||||||
|
Set("countRequests", countRequests).
|
||||||
|
Set("countAttackRequests", countAttackRequests).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
} else {
|
} else {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Set("bandwidthTime", fullTime).
|
Set("bandwidthTime", fullTime).
|
||||||
Set("bandwidthBytes", dbs.SQL("bandwidthBytes+:bytes")).
|
Set("bandwidthBytes", dbs.SQL("bandwidthBytes+:bytes")).
|
||||||
|
Set("countRequests", dbs.SQL("countRequests+:countRequests")).
|
||||||
|
Set("countAttackRequests", dbs.SQL("countAttackRequests+:countAttackRequests")).
|
||||||
Param("bytes", bandwidthBytes).
|
Param("bytes", bandwidthBytes).
|
||||||
|
Param("countRequests", countRequests).
|
||||||
|
Param("countAttackRequests", countAttackRequests).
|
||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2832,6 +2883,10 @@ func (this *ServerDAO) FindEnabledServersWithIds(tx *dbs.Tx, serverIds []int64)
|
|||||||
|
|
||||||
// NotifyUpdate 同步服务所在的集群
|
// NotifyUpdate 同步服务所在的集群
|
||||||
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// 创建任务
|
// 创建任务
|
||||||
clusterId, err := this.FindServerClusterId(tx, serverId)
|
clusterId, err := this.FindServerClusterId(tx, serverId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -2845,6 +2900,9 @@ func (this *ServerDAO) NotifyUpdate(tx *dbs.Tx, serverId int64) error {
|
|||||||
|
|
||||||
// NotifyClusterUpdate 同步指定的集群
|
// NotifyClusterUpdate 同步指定的集群
|
||||||
func (this *ServerDAO) NotifyClusterUpdate(tx *dbs.Tx, clusterId, serverId int64) error {
|
func (this *ServerDAO) NotifyClusterUpdate(tx *dbs.Tx, clusterId, serverId int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if clusterId <= 0 {
|
if clusterId <= 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -2853,6 +2911,10 @@ func (this *ServerDAO) NotifyClusterUpdate(tx *dbs.Tx, clusterId, serverId int64
|
|||||||
|
|
||||||
// NotifyDNSUpdate 通知当前集群DNS更新
|
// NotifyDNSUpdate 通知当前集群DNS更新
|
||||||
func (this *ServerDAO) NotifyDNSUpdate(tx *dbs.Tx, serverId int64) error {
|
func (this *ServerDAO) NotifyDNSUpdate(tx *dbs.Tx, serverId int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
clusterId, err := this.Query(tx).
|
clusterId, err := this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
Result("clusterId").
|
Result("clusterId").
|
||||||
@@ -2878,6 +2940,10 @@ func (this *ServerDAO) NotifyDNSUpdate(tx *dbs.Tx, serverId int64) error {
|
|||||||
|
|
||||||
// NotifyClusterDNSUpdate 通知某个集群中的DNS更新
|
// NotifyClusterDNSUpdate 通知某个集群中的DNS更新
|
||||||
func (this *ServerDAO) NotifyClusterDNSUpdate(tx *dbs.Tx, clusterId int64, serverId int64) error {
|
func (this *ServerDAO) NotifyClusterDNSUpdate(tx *dbs.Tx, clusterId int64, serverId int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
dnsInfo, err := SharedNodeClusterDAO.FindClusterDNSInfo(tx, clusterId, nil)
|
dnsInfo, err := SharedNodeClusterDAO.FindClusterDNSInfo(tx, clusterId, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -2893,6 +2959,10 @@ func (this *ServerDAO) NotifyClusterDNSUpdate(tx *dbs.Tx, clusterId int64, serve
|
|||||||
|
|
||||||
// NotifyDisable 通知禁用
|
// NotifyDisable 通知禁用
|
||||||
func (this *ServerDAO) NotifyDisable(tx *dbs.Tx, serverId int64) error {
|
func (this *ServerDAO) NotifyDisable(tx *dbs.Tx, serverId int64) error {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// 禁用缓存策略相关的内容
|
// 禁用缓存策略相关的内容
|
||||||
policyIds, err := SharedHTTPFirewallPolicyDAO.FindFirewallPolicyIdsWithServerId(tx, serverId)
|
policyIds, err := SharedHTTPFirewallPolicyDAO.FindFirewallPolicyIdsWithServerId(tx, serverId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ func TestServerDAO_FindEnabledServerWithDomain(t *testing.T) {
|
|||||||
|
|
||||||
for _, domain := range []string{"a", "a.com", "teaos.cn", "www.teaos.cn", "cdn.teaos.cn", "google.com"} {
|
for _, domain := range []string{"a", "a.com", "teaos.cn", "www.teaos.cn", "cdn.teaos.cn", "google.com"} {
|
||||||
var before = time.Now()
|
var before = time.Now()
|
||||||
server, err := dao.FindEnabledServerWithDomain(tx, domain)
|
server, err := dao.FindEnabledServerWithDomain(tx, 0, domain)
|
||||||
var costMs = time.Since(before).Seconds() * 1000
|
var costMs = time.Since(before).Seconds() * 1000
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -326,7 +326,7 @@ func TestServerDAO_FindBool(t *testing.T) {
|
|||||||
func TestServerDAO_UpdateServerBandwidth(t *testing.T) {
|
func TestServerDAO_UpdateServerBandwidth(t *testing.T) {
|
||||||
var dao = models.NewServerDAO()
|
var dao = models.NewServerDAO()
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
err := dao.UpdateServerBandwidth(tx, 1, timeutil.FormatTime("YmdHi", time.Now().Unix()/300*300), 1024)
|
err := dao.UpdateServerBandwidth(tx, 1, timeutil.FormatTime("YmdHi", time.Now().Unix()/300*300), 1024, 1, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,57 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
ServerField_Id dbs.FieldName = "id" // ID
|
||||||
|
ServerField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
ServerField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
ServerField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
ServerField_Type dbs.FieldName = "type" // 服务类型
|
||||||
|
ServerField_Name dbs.FieldName = "name" // 名称
|
||||||
|
ServerField_Description dbs.FieldName = "description" // 描述
|
||||||
|
ServerField_PlainServerNames dbs.FieldName = "plainServerNames" // 扁平化域名列表
|
||||||
|
ServerField_ServerNames dbs.FieldName = "serverNames" // 域名列表
|
||||||
|
ServerField_AuditingAt dbs.FieldName = "auditingAt" // 审核提交时间
|
||||||
|
ServerField_AuditingServerNames dbs.FieldName = "auditingServerNames" // 审核中的域名
|
||||||
|
ServerField_IsAuditing dbs.FieldName = "isAuditing" // 是否正在审核
|
||||||
|
ServerField_AuditingResult dbs.FieldName = "auditingResult" // 审核结果
|
||||||
|
ServerField_Http dbs.FieldName = "http" // HTTP配置
|
||||||
|
ServerField_Https dbs.FieldName = "https" // HTTPS配置
|
||||||
|
ServerField_Tcp dbs.FieldName = "tcp" // TCP配置
|
||||||
|
ServerField_Tls dbs.FieldName = "tls" // TLS配置
|
||||||
|
ServerField_Unix dbs.FieldName = "unix" // Unix配置
|
||||||
|
ServerField_Udp dbs.FieldName = "udp" // UDP配置
|
||||||
|
ServerField_WebId dbs.FieldName = "webId" // WEB配置
|
||||||
|
ServerField_ReverseProxy dbs.FieldName = "reverseProxy" // 反向代理配置
|
||||||
|
ServerField_GroupIds dbs.FieldName = "groupIds" // 分组ID列表
|
||||||
|
ServerField_Config dbs.FieldName = "config" // 服务配置,自动生成
|
||||||
|
ServerField_ConfigMd5 dbs.FieldName = "configMd5" // Md5
|
||||||
|
ServerField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||||
|
ServerField_IncludeNodes dbs.FieldName = "includeNodes" // 部署条件
|
||||||
|
ServerField_ExcludeNodes dbs.FieldName = "excludeNodes" // 节点排除条件
|
||||||
|
ServerField_Version dbs.FieldName = "version" // 版本号
|
||||||
|
ServerField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
ServerField_State dbs.FieldName = "state" // 状态
|
||||||
|
ServerField_DnsName dbs.FieldName = "dnsName" // DNS名称
|
||||||
|
ServerField_TcpPorts dbs.FieldName = "tcpPorts" // 所包含TCP端口
|
||||||
|
ServerField_UdpPorts dbs.FieldName = "udpPorts" // 所包含UDP端口
|
||||||
|
ServerField_SupportCNAME dbs.FieldName = "supportCNAME" // 允许CNAME不在域名名单
|
||||||
|
ServerField_TrafficLimit dbs.FieldName = "trafficLimit" // 流量限制
|
||||||
|
ServerField_TrafficDay dbs.FieldName = "trafficDay" // YYYYMMDD
|
||||||
|
ServerField_TrafficMonth dbs.FieldName = "trafficMonth" // YYYYMM
|
||||||
|
ServerField_TotalDailyTraffic dbs.FieldName = "totalDailyTraffic" // 日流量
|
||||||
|
ServerField_TotalMonthlyTraffic dbs.FieldName = "totalMonthlyTraffic" // 月流量
|
||||||
|
ServerField_TrafficLimitStatus dbs.FieldName = "trafficLimitStatus" // 流量限制状态
|
||||||
|
ServerField_TotalTraffic dbs.FieldName = "totalTraffic" // 总流量
|
||||||
|
ServerField_UserPlanId dbs.FieldName = "userPlanId" // 所属套餐ID
|
||||||
|
ServerField_LastUserPlanId dbs.FieldName = "lastUserPlanId" // 上一次使用的套餐
|
||||||
|
ServerField_Uam dbs.FieldName = "uam" // UAM设置
|
||||||
|
ServerField_BandwidthTime dbs.FieldName = "bandwidthTime" // 带宽更新时间,YYYYMMDDHHII
|
||||||
|
ServerField_BandwidthBytes dbs.FieldName = "bandwidthBytes" // 最近带宽峰值
|
||||||
|
ServerField_CountAttackRequests dbs.FieldName = "countAttackRequests" // 最近攻击请求数
|
||||||
|
ServerField_CountRequests dbs.FieldName = "countRequests" // 最近总请求数
|
||||||
|
)
|
||||||
|
|
||||||
// Server 服务
|
// Server 服务
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -50,6 +101,8 @@ type Server struct {
|
|||||||
Uam dbs.JSON `field:"uam"` // UAM设置
|
Uam dbs.JSON `field:"uam"` // UAM设置
|
||||||
BandwidthTime string `field:"bandwidthTime"` // 带宽更新时间,YYYYMMDDHHII
|
BandwidthTime string `field:"bandwidthTime"` // 带宽更新时间,YYYYMMDDHHII
|
||||||
BandwidthBytes uint64 `field:"bandwidthBytes"` // 最近带宽峰值
|
BandwidthBytes uint64 `field:"bandwidthBytes"` // 最近带宽峰值
|
||||||
|
CountAttackRequests uint64 `field:"countAttackRequests"` // 最近攻击请求数
|
||||||
|
CountRequests uint64 `field:"countRequests"` // 最近总请求数
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerOperator struct {
|
type ServerOperator struct {
|
||||||
@@ -99,6 +152,8 @@ type ServerOperator struct {
|
|||||||
Uam any // UAM设置
|
Uam any // UAM设置
|
||||||
BandwidthTime any // 带宽更新时间,YYYYMMDDHHII
|
BandwidthTime any // 带宽更新时间,YYYYMMDDHHII
|
||||||
BandwidthBytes any // 最近带宽峰值
|
BandwidthBytes any // 最近带宽峰值
|
||||||
|
CountAttackRequests any // 最近攻击请求数
|
||||||
|
CountRequests any // 最近总请求数
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServerOperator() *ServerOperator {
|
func NewServerOperator() *ServerOperator {
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ func (this *SSLPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, ignore
|
|||||||
config.Id = int64(policy.Id)
|
config.Id = int64(policy.Id)
|
||||||
config.IsOn = policy.IsOn
|
config.IsOn = policy.IsOn
|
||||||
config.ClientAuthType = int(policy.ClientAuthType)
|
config.ClientAuthType = int(policy.ClientAuthType)
|
||||||
config.HTTP2Enabled = policy.Http2Enabled == 1
|
config.HTTP2Enabled = policy.Http2Enabled
|
||||||
|
config.HTTP3Enabled = policy.Http3Enabled
|
||||||
config.MinVersion = policy.MinVersion
|
config.MinVersion = policy.MinVersion
|
||||||
|
|
||||||
// certs
|
// certs
|
||||||
@@ -200,7 +201,7 @@ func (this *SSLPolicyDAO) FindAllEnabledPolicyIdsWithCertId(tx *dbs.Tx, certId i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreatePolicy 创建Policy
|
// CreatePolicy 创建Policy
|
||||||
func (this *SSLPolicyDAO) CreatePolicy(tx *dbs.Tx, adminId int64, userId int64, http2Enabled bool, minVersion string, certsJSON []byte, hstsJSON []byte, ocspIsOn bool, clientAuthType int32, clientCACertsJSON []byte, cipherSuitesIsOn bool, cipherSuites []string) (int64, error) {
|
func (this *SSLPolicyDAO) CreatePolicy(tx *dbs.Tx, adminId int64, userId int64, http2Enabled bool, http3Enabled bool, minVersion string, certsJSON []byte, hstsJSON []byte, ocspIsOn bool, clientAuthType int32, clientCACertsJSON []byte, cipherSuitesIsOn bool, cipherSuites []string) (int64, error) {
|
||||||
var op = NewSSLPolicyOperator()
|
var op = NewSSLPolicyOperator()
|
||||||
op.State = SSLPolicyStateEnabled
|
op.State = SSLPolicyStateEnabled
|
||||||
op.IsOn = true
|
op.IsOn = true
|
||||||
@@ -208,6 +209,7 @@ func (this *SSLPolicyDAO) CreatePolicy(tx *dbs.Tx, adminId int64, userId int64,
|
|||||||
op.UserId = userId
|
op.UserId = userId
|
||||||
|
|
||||||
op.Http2Enabled = http2Enabled
|
op.Http2Enabled = http2Enabled
|
||||||
|
op.Http3Enabled = http3Enabled
|
||||||
op.MinVersion = minVersion
|
op.MinVersion = minVersion
|
||||||
|
|
||||||
if len(certsJSON) > 0 {
|
if len(certsJSON) > 0 {
|
||||||
@@ -240,7 +242,7 @@ func (this *SSLPolicyDAO) CreatePolicy(tx *dbs.Tx, adminId int64, userId int64,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePolicy 修改Policy
|
// UpdatePolicy 修改Policy
|
||||||
func (this *SSLPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, http2Enabled bool, minVersion string, certsJSON []byte, hstsJSON []byte, ocspIsOn bool, clientAuthType int32, clientCACertsJSON []byte, cipherSuitesIsOn bool, cipherSuites []string) error {
|
func (this *SSLPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, http2Enabled bool, http3Enabled bool, minVersion string, certsJSON []byte, hstsJSON []byte, ocspIsOn bool, clientAuthType int32, clientCACertsJSON []byte, cipherSuitesIsOn bool, cipherSuites []string) error {
|
||||||
if policyId <= 0 {
|
if policyId <= 0 {
|
||||||
return errors.New("invalid policyId")
|
return errors.New("invalid policyId")
|
||||||
}
|
}
|
||||||
@@ -248,6 +250,7 @@ func (this *SSLPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, http2Enabled
|
|||||||
var op = NewSSLPolicyOperator()
|
var op = NewSSLPolicyOperator()
|
||||||
op.Id = policyId
|
op.Id = policyId
|
||||||
op.Http2Enabled = http2Enabled
|
op.Http2Enabled = http2Enabled
|
||||||
|
op.Http3Enabled = http3Enabled
|
||||||
op.MinVersion = minVersion
|
op.MinVersion = minVersion
|
||||||
|
|
||||||
if len(certsJSON) > 0 {
|
if len(certsJSON) > 0 {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type SSLPolicy struct {
|
|||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
UserId uint32 `field:"userId"` // 用户ID
|
UserId uint32 `field:"userId"` // 用户ID
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
Certs dbs.JSON `field:"certs"` // 证书列表
|
Certs dbs.JSON `field:"certs"` // 证书列表
|
||||||
ClientCACerts dbs.JSON `field:"clientCACerts"` // 客户端证书
|
ClientCACerts dbs.JSON `field:"clientCACerts"` // 客户端证书
|
||||||
ClientAuthType uint32 `field:"clientAuthType"` // 客户端认证类型
|
ClientAuthType uint32 `field:"clientAuthType"` // 客户端认证类型
|
||||||
@@ -15,28 +15,30 @@ type SSLPolicy struct {
|
|||||||
CipherSuitesIsOn uint8 `field:"cipherSuitesIsOn"` // 是否自定义加密算法套件
|
CipherSuitesIsOn uint8 `field:"cipherSuitesIsOn"` // 是否自定义加密算法套件
|
||||||
CipherSuites dbs.JSON `field:"cipherSuites"` // 加密算法套件
|
CipherSuites dbs.JSON `field:"cipherSuites"` // 加密算法套件
|
||||||
Hsts dbs.JSON `field:"hsts"` // HSTS设置
|
Hsts dbs.JSON `field:"hsts"` // HSTS设置
|
||||||
Http2Enabled uint8 `field:"http2Enabled"` // 是否启用HTTP/2
|
Http2Enabled bool `field:"http2Enabled"` // 是否启用HTTP/2
|
||||||
|
Http3Enabled bool `field:"http3Enabled"` // 是否启用HTTP/3
|
||||||
OcspIsOn uint8 `field:"ocspIsOn"` // 是否启用OCSP
|
OcspIsOn uint8 `field:"ocspIsOn"` // 是否启用OCSP
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
}
|
}
|
||||||
|
|
||||||
type SSLPolicyOperator struct {
|
type SSLPolicyOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
Certs interface{} // 证书列表
|
Certs any // 证书列表
|
||||||
ClientCACerts interface{} // 客户端证书
|
ClientCACerts any // 客户端证书
|
||||||
ClientAuthType interface{} // 客户端认证类型
|
ClientAuthType any // 客户端认证类型
|
||||||
MinVersion interface{} // 支持的SSL最小版本
|
MinVersion any // 支持的SSL最小版本
|
||||||
CipherSuitesIsOn interface{} // 是否自定义加密算法套件
|
CipherSuitesIsOn any // 是否自定义加密算法套件
|
||||||
CipherSuites interface{} // 加密算法套件
|
CipherSuites any // 加密算法套件
|
||||||
Hsts interface{} // HSTS设置
|
Hsts any // HSTS设置
|
||||||
Http2Enabled interface{} // 是否启用HTTP/2
|
Http2Enabled any // 是否启用HTTP/2
|
||||||
OcspIsOn interface{} // 是否启用OCSP
|
Http3Enabled any // 是否启用HTTP/3
|
||||||
State interface{} // 状态
|
OcspIsOn any // 是否启用OCSP
|
||||||
CreatedAt interface{} // 创建时间
|
State any // 状态
|
||||||
|
CreatedAt any // 创建时间
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSSLPolicyOperator() *SSLPolicyOperator {
|
func NewSSLPolicyOperator() *SSLPolicyOperator {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"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"
|
||||||
@@ -22,7 +23,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedNodeClusterTrafficDailyStatDAO.Clean(nil, 30) // 只保留N天
|
err := SharedNodeClusterTrafficDailyStatDAO.CleanDefaultDays(nil, 30) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("NodeClusterTrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("NodeClusterTrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -128,11 +129,27 @@ func (this *NodeClusterTrafficDailyStatDAO) SumDailyStat(tx *dbs.Tx, clusterId i
|
|||||||
return one.(*NodeClusterTrafficDailyStat), nil
|
return one.(*NodeClusterTrafficDailyStat), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *NodeClusterTrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *NodeClusterTrafficDailyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("day", day).
|
Lt("day", day).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *NodeClusterTrafficDailyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.NodeClusterTrafficDailyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.NodeClusterTrafficDailyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"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"
|
||||||
@@ -22,7 +23,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedNodeTrafficHourlyStatDAO.Clean(nil, 15) // 只保留N天
|
err := SharedNodeTrafficHourlyStatDAO.CleanDefaultDays(nil, 15) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("NodeTrafficHourlyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("NodeTrafficHourlyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -197,11 +198,27 @@ func (this *NodeTrafficHourlyStatDAO) FindHourlyStatsWithNodeId(tx *dbs.Tx, role
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *NodeTrafficHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *NodeTrafficHourlyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("hour", hour).
|
Lt("hour", hour).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *NodeTrafficHourlyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.NodeTrafficHourlyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.NodeTrafficHourlyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 15
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"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"
|
||||||
@@ -25,7 +26,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedServerDomainHourlyStatDAO.Clean(nil, 7) // 只保留 N 天
|
err := SharedServerDomainHourlyStatDAO.CleanDefaultDays(nil, 7) // 只保留 N 天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("ServerDomainHourlyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("ServerDomainHourlyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -366,8 +367,8 @@ func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithServerId(tx *dbs.Tx
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *ServerDomainHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *ServerDomainHourlyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
||||||
for _, table := range this.FindAllPartitionTables() {
|
for _, table := range this.FindAllPartitionTables() {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
@@ -380,3 +381,19 @@ func (this *ServerDomainHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *ServerDomainHourlyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.ServerDomainHourlyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.ServerDomainHourlyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 7
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"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"
|
||||||
@@ -22,7 +23,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedTrafficDailyStatDAO.Clean(nil, 30) // 只保留N天
|
err := SharedTrafficDailyStatDAO.CleanDefaultDays(nil, 30) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("TrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("TrafficDailyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -124,11 +125,27 @@ func (this *TrafficDailyStatDAO) FindDailyStat(tx *dbs.Tx, day string) (*Traffic
|
|||||||
return one.(*TrafficDailyStat), nil
|
return one.(*TrafficDailyStat), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *TrafficDailyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *TrafficDailyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("day", day).
|
Lt("day", day).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *TrafficDailyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.TrafficDailyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.TrafficDailyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"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"
|
||||||
@@ -22,7 +23,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedTrafficHourlyStatDAO.Clean(nil, 15) // 只保留N天
|
err := SharedTrafficHourlyStatDAO.CleanDefaultDays(nil, 15) // 只保留N天
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("TrafficHourlyStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("TrafficHourlyStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -137,11 +138,27 @@ func (this *TrafficHourlyStatDAO) SumHourlyStats(tx *dbs.Tx, hourFrom string, ho
|
|||||||
return one.(*TrafficHourlyStat), nil
|
return one.(*TrafficHourlyStat), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// CleanDays 清理历史数据
|
||||||
func (this *TrafficHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *TrafficHourlyStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Lt("hour", hour).
|
Lt("hour", hour).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *TrafficHourlyStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := models.SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.TrafficHourlyStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.TrafficHourlyStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 15
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,23 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/zero"
|
||||||
_ "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/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SysLockerDAO dbs.DAO
|
type SysLockerDAO dbs.DAO
|
||||||
|
|
||||||
|
// concurrent transactions control
|
||||||
|
// 考虑到存在多个API节点的可能性,容量不能太大,也不能使用mutex
|
||||||
|
var sysLockerConcurrentLimiter = make(chan zero.Zero, 8)
|
||||||
|
|
||||||
func NewSysLockerDAO() *SysLockerDAO {
|
func NewSysLockerDAO() *SysLockerDAO {
|
||||||
return dbs.NewDAO(&SysLockerDAO{
|
return dbs.NewDAO(&SysLockerDAO{
|
||||||
DAOObject: dbs.DAOObject{
|
DAOObject: dbs.DAOObject{
|
||||||
@@ -114,9 +121,20 @@ func (this *SysLockerDAO) Unlock(tx *dbs.Tx, key string) error {
|
|||||||
|
|
||||||
// Increase 增加版本号
|
// Increase 增加版本号
|
||||||
func (this *SysLockerDAO) Increase(tx *dbs.Tx, key string, defaultValue int64) (int64, error) {
|
func (this *SysLockerDAO) Increase(tx *dbs.Tx, key string, defaultValue int64) (int64, error) {
|
||||||
|
// validate key
|
||||||
|
if strings.Contains(key, "'") {
|
||||||
|
return 0, errors.New("invalid key '" + key + "'")
|
||||||
|
}
|
||||||
|
|
||||||
if tx == nil {
|
if tx == nil {
|
||||||
var result int64
|
var result int64
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
sysLockerConcurrentLimiter <- zero.Zero{} // push
|
||||||
|
defer func() {
|
||||||
|
<-sysLockerConcurrentLimiter // pop
|
||||||
|
}()
|
||||||
|
|
||||||
err = this.Instance.RunTx(func(tx *dbs.Tx) error {
|
err = this.Instance.RunTx(func(tx *dbs.Tx) error {
|
||||||
result, err = this.Increase(tx, key, defaultValue)
|
result, err = this.Increase(tx, key, defaultValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -126,7 +144,22 @@ func (this *SysLockerDAO) Increase(tx *dbs.Tx, key string, defaultValue int64) (
|
|||||||
})
|
})
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
err := this.Query(tx).
|
|
||||||
|
// combine statements to make increasing faster
|
||||||
|
colValue, err := tx.FindCol(0, "INSERT INTO `"+this.Table+"` (`key`, `version`) VALUES ('"+key+"', "+types.String(defaultValue)+") ON DUPLICATE KEY UPDATE `version`=`version`+1; SELECT `version` FROM `"+this.Table+"` WHERE `key`='"+key+"'")
|
||||||
|
if err != nil {
|
||||||
|
if CheckSQLErrCode(err, 1064 /** syntax error **/) {
|
||||||
|
// continue to use seperated query
|
||||||
|
err = nil
|
||||||
|
} else {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return types.Int64(colValue), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = this.Query(tx).
|
||||||
|
Reuse(false). // no need to prepare statement in every transaction
|
||||||
InsertOrUpdateQuickly(maps.Map{
|
InsertOrUpdateQuickly(maps.Map{
|
||||||
"key": key,
|
"key": key,
|
||||||
"version": defaultValue,
|
"version": defaultValue,
|
||||||
@@ -137,12 +170,12 @@ func (this *SysLockerDAO) Increase(tx *dbs.Tx, key string, defaultValue int64) (
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
|
Reuse(false). // no need to prepare statement in every transaction
|
||||||
Attr("key", key).
|
Attr("key", key).
|
||||||
Result("version").
|
Result("version").
|
||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 读取当前版本号
|
// 读取当前版本号
|
||||||
func (this *SysLockerDAO) Read(tx *dbs.Tx, key string) (int64, error) {
|
func (this *SysLockerDAO) Read(tx *dbs.Tx, key string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
|
|||||||
@@ -3,44 +3,146 @@ package models
|
|||||||
import (
|
import (
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSysLockerDAO_Lock(t *testing.T) {
|
func TestSysLockerDAO_Lock(t *testing.T) {
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
|
|
||||||
isOk, err := SharedSysLockerDAO.Lock(tx, "test", 600)
|
var dao = NewSysLockerDAO()
|
||||||
|
|
||||||
|
isOk, err := dao.Lock(tx, "test", 600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Log(isOk)
|
t.Log(isOk)
|
||||||
|
|
||||||
if isOk {
|
if isOk {
|
||||||
err = SharedSysLockerDAO.Unlock(tx, "test")
|
err = dao.Unlock(tx, "test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSysLocker_Increase_SQL(t *testing.T) {
|
||||||
|
var dao = NewSysLockerDAO()
|
||||||
|
value, err := dao.Read(nil, "hello")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("before:", value)
|
||||||
|
v, err := dao.Increase(nil, "hello", 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Log("err:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Log("after:", v)
|
||||||
|
}
|
||||||
|
|
||||||
func TestSysLocker_Increase(t *testing.T) {
|
func TestSysLocker_Increase(t *testing.T) {
|
||||||
count := 100
|
dbs.NotifyReady()
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
|
var count = 1000
|
||||||
|
|
||||||
|
var dao = NewSysLockerDAO()
|
||||||
|
value, err := dao.Read(nil, "hello")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("before", value)
|
||||||
|
|
||||||
|
var locker = sync.Mutex{}
|
||||||
|
var allValueMap = map[int64]bool{}
|
||||||
|
|
||||||
|
var before = time.Now()
|
||||||
|
|
||||||
|
var wg = sync.WaitGroup{}
|
||||||
wg.Add(count)
|
wg.Add(count)
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
go func() {
|
go func(i int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
v, err := NewSysLockerDAO().Increase(nil, "hello", 0)
|
|
||||||
|
var key = "hello"
|
||||||
|
v, err := dao.Increase(nil, key, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log("err:", err)
|
t.Log("err:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.Log("v:", v)
|
|
||||||
}()
|
locker.Lock()
|
||||||
|
if allValueMap[v] {
|
||||||
|
t.Log("duplicated:", v)
|
||||||
|
} else {
|
||||||
|
allValueMap[v] = true
|
||||||
|
}
|
||||||
|
locker.Unlock()
|
||||||
|
|
||||||
|
//t.Log("v:", v)
|
||||||
|
_ = v
|
||||||
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
t.Log("ok")
|
|
||||||
|
t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
|
||||||
|
|
||||||
|
value, err = dao.Read(nil, "hello")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("after", value, "values:", len(allValueMap))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSysLocker_Increase_Performance(t *testing.T) {
|
||||||
|
dbs.NotifyReady()
|
||||||
|
|
||||||
|
var count = 1000
|
||||||
|
|
||||||
|
var dao = NewSysLockerDAO()
|
||||||
|
|
||||||
|
var before = time.Now()
|
||||||
|
|
||||||
|
var wg = sync.WaitGroup{}
|
||||||
|
wg.Add(count)
|
||||||
|
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
go func(i int) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
var key = "hello" + types.String(i%10)
|
||||||
|
v, err := dao.Increase(nil, key, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Log("err:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//t.Log("v:", v)
|
||||||
|
_ = v
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSysLockerDAO_Increase(b *testing.B) {
|
||||||
|
var dao = NewSysLockerDAO()
|
||||||
|
_, _ = dao.Increase(nil, "hello", 0)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
_, err := dao.Increase(nil, "hello", 0)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,3 +262,20 @@ func (this *SysSettingDAO) ReadUserRegisterConfig(tx *dbs.Tx) (*userconfigs.User
|
|||||||
}
|
}
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *SysSettingDAO) ReadDatabaseConfig(tx *dbs.Tx) (config *systemconfigs.DatabaseConfig, err error) {
|
||||||
|
valueJSON, err := this.ReadSetting(tx, systemconfigs.SettingCodeDatabaseConfigSetting)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(valueJSON) == 0 {
|
||||||
|
return systemconfigs.NewDatabaseConfig(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
config = systemconfigs.NewDatabaseConfig()
|
||||||
|
err = json.Unmarshal(valueJSON, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func init() {
|
|||||||
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
var ticker = time.NewTicker(time.Duration(rands.Int(24, 48)) * time.Hour)
|
||||||
goman.New(func() {
|
goman.New(func() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
err := SharedUserBandwidthStatDAO.Clean(nil)
|
err := SharedUserBandwidthStatDAO.CleanDefaultDays(nil, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("SharedUserBandwidthStatDAO", "clean expired data failed: "+err.Error())
|
remotelogs.Error("SharedUserBandwidthStatDAO", "clean expired data failed: "+err.Error())
|
||||||
}
|
}
|
||||||
@@ -460,9 +460,9 @@ func (this *UserBandwidthStatDAO) SumDailyStat(tx *dbs.Tx, userId int64, regionI
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理过期数据
|
// CleanDays 清理过期数据
|
||||||
func (this *UserBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
func (this *UserBandwidthStatDAO) CleanDays(tx *dbs.Tx, days int) error {
|
||||||
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -100)) // 保留大约3个月的数据
|
var day = timeutil.Format("Ymd", time.Now().AddDate(0, 0, -days)) // 保留大约3个月的数据
|
||||||
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Table(table).
|
Table(table).
|
||||||
@@ -472,6 +472,22 @@ func (this *UserBandwidthStatDAO) Clean(tx *dbs.Tx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *UserBandwidthStatDAO) CleanDefaultDays(tx *dbs.Tx, defaultDays int) error {
|
||||||
|
databaseConfig, err := SharedSysSettingDAO.ReadDatabaseConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if databaseConfig != nil && databaseConfig.UserBandwidthStat.Clean.Days > 0 {
|
||||||
|
defaultDays = databaseConfig.UserBandwidthStat.Clean.Days
|
||||||
|
}
|
||||||
|
if defaultDays <= 0 {
|
||||||
|
defaultDays = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.CleanDays(tx, defaultDays)
|
||||||
|
}
|
||||||
|
|
||||||
// 批量执行
|
// 批量执行
|
||||||
func (this *UserBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
func (this *UserBandwidthStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
||||||
var locker = &sync.Mutex{}
|
var locker = &sync.Mutex{}
|
||||||
|
|||||||
@@ -57,10 +57,10 @@ func TestUserBandwidthStatDAO_UpdateServerBandwidth(t *testing.T) {
|
|||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUserBandwidthStatDAO_Clean(t *testing.T) {
|
func TestUserBandwidthStatDAO_CleanDays(t *testing.T) {
|
||||||
var dao = models.NewUserBandwidthStatDAO()
|
var dao = models.NewUserBandwidthStatDAO()
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
err := dao.Clean(tx)
|
err := dao.CleanDays(tx, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,42 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserField_Id dbs.FieldName = "id" // ID
|
||||||
|
UserField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
UserField_Username dbs.FieldName = "username" // 用户名
|
||||||
|
UserField_Password dbs.FieldName = "password" // 密码
|
||||||
|
UserField_Fullname dbs.FieldName = "fullname" // 真实姓名
|
||||||
|
UserField_Mobile dbs.FieldName = "mobile" // 手机号
|
||||||
|
UserField_VerifiedMobile dbs.FieldName = "verifiedMobile" // 已验证手机号
|
||||||
|
UserField_Tel dbs.FieldName = "tel" // 联系电话
|
||||||
|
UserField_Remark dbs.FieldName = "remark" // 备注
|
||||||
|
UserField_Email dbs.FieldName = "email" // 邮箱地址
|
||||||
|
UserField_VerifiedEmail dbs.FieldName = "verifiedEmail" // 激活后的邮箱
|
||||||
|
UserField_EmailIsVerified dbs.FieldName = "emailIsVerified" // 邮箱是否已验证
|
||||||
|
UserField_AvatarFileId dbs.FieldName = "avatarFileId" // 头像文件ID
|
||||||
|
UserField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
UserField_Day dbs.FieldName = "day" // YYYYMMDD
|
||||||
|
UserField_UpdatedAt dbs.FieldName = "updatedAt" // 修改时间
|
||||||
|
UserField_State dbs.FieldName = "state" // 状态
|
||||||
|
UserField_Source dbs.FieldName = "source" // 来源
|
||||||
|
UserField_ClusterId dbs.FieldName = "clusterId" // 集群ID
|
||||||
|
UserField_Features dbs.FieldName = "features" // 允许操作的特征
|
||||||
|
UserField_RegisteredIP dbs.FieldName = "registeredIP" // 注册使用的IP
|
||||||
|
UserField_IsRejected dbs.FieldName = "isRejected" // 是否已拒绝
|
||||||
|
UserField_RejectReason dbs.FieldName = "rejectReason" // 拒绝理由
|
||||||
|
UserField_IsVerified dbs.FieldName = "isVerified" // 是否验证通过
|
||||||
|
UserField_RequirePlans dbs.FieldName = "requirePlans" // 是否需要购买套餐
|
||||||
|
UserField_Modules dbs.FieldName = "modules" // 用户模块
|
||||||
|
UserField_PriceType dbs.FieldName = "priceType" // 计费类型:traffic|bandwidth
|
||||||
|
UserField_PricePeriod dbs.FieldName = "pricePeriod" // 结算周期
|
||||||
|
UserField_ServersEnabled dbs.FieldName = "serversEnabled" // 是否禁用所有服务
|
||||||
|
UserField_Notification dbs.FieldName = "notification" // 通知设置
|
||||||
|
UserField_BandwidthAlgo dbs.FieldName = "bandwidthAlgo" // 带宽算法
|
||||||
|
UserField_BandwidthModifier dbs.FieldName = "bandwidthModifier" // 带宽修正值
|
||||||
|
UserField_Lang dbs.FieldName = "lang" // 语言代号
|
||||||
|
)
|
||||||
|
|
||||||
// User 用户
|
// User 用户
|
||||||
type User struct {
|
type User struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -36,6 +72,7 @@ type User struct {
|
|||||||
Notification dbs.JSON `field:"notification"` // 通知设置
|
Notification dbs.JSON `field:"notification"` // 通知设置
|
||||||
BandwidthAlgo string `field:"bandwidthAlgo"` // 带宽算法
|
BandwidthAlgo string `field:"bandwidthAlgo"` // 带宽算法
|
||||||
BandwidthModifier float64 `field:"bandwidthModifier"` // 带宽修正值
|
BandwidthModifier float64 `field:"bandwidthModifier"` // 带宽修正值
|
||||||
|
Lang string `field:"lang"` // 语言代号
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserOperator struct {
|
type UserOperator struct {
|
||||||
@@ -71,6 +108,7 @@ type UserOperator struct {
|
|||||||
Notification any // 通知设置
|
Notification any // 通知设置
|
||||||
BandwidthAlgo any // 带宽算法
|
BandwidthAlgo any // 带宽算法
|
||||||
BandwidthModifier any // 带宽修正值
|
BandwidthModifier any // 带宽修正值
|
||||||
|
Lang any // 语言代号
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserOperator() *UserOperator {
|
func NewUserOperator() *UserOperator {
|
||||||
|
|||||||
@@ -280,6 +280,7 @@ func (this *UserNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, nodeStatus *
|
|||||||
func (this *UserNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
func (this *UserNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(UserNodeStateEnabled).
|
State(UserNodeStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
Where("status IS NOT NULL").
|
Where("status IS NOT NULL").
|
||||||
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
||||||
Param("version", utils.VersionToLong(version)).
|
Param("version", utils.VersionToLong(version)).
|
||||||
|
|||||||
@@ -80,3 +80,12 @@ func CheckSQLDuplicateErr(err error) bool {
|
|||||||
}
|
}
|
||||||
return CheckSQLErrCode(err, 1062)
|
return CheckSQLErrCode(err, 1062)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsMySQLError Check error is MySQLError
|
||||||
|
func IsMySQLError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, ok := err.(*mysql.MySQLError)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
package dbutils
|
package dbutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
executils "github.com/TeaOSLab/EdgeAPI/internal/utils/exec"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/lists"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewQuery 构造Query
|
// NewQuery 构造Query
|
||||||
@@ -127,3 +135,79 @@ func MySQLVersionFrom8() (bool, error) {
|
|||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindMySQLPath find out mysqld_safe path from system processes
|
||||||
|
func FindMySQLPath() string {
|
||||||
|
psExe, err := executils.LookPath("ps")
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var cmd = executils.NewTimeoutCmd(3*time.Second, psExe, "-ef").
|
||||||
|
WithStdout().
|
||||||
|
WithStderr()
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var reg = regexp.MustCompile(`\s(/\S+/mysqld_safe)\s`)
|
||||||
|
var matches = reg.FindStringSubmatch(cmd.Stdout())
|
||||||
|
if len(matches) > 1 {
|
||||||
|
var path = matches[1]
|
||||||
|
_, err = os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindMySQLPathAndRemember find out mysqld_safe path then remember it for future usage
|
||||||
|
func FindMySQLPathAndRemember() {
|
||||||
|
var path = FindMySQLPath()
|
||||||
|
if len(path) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var cacheFile = Tea.Root + "/data/mysql-path.cache"
|
||||||
|
_ = os.WriteFile(cacheFile, []byte(path), 0666) // ignore error
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartLocalMySQL try to start local mysql server
|
||||||
|
func StartLocalMySQL() {
|
||||||
|
// possible installed paths
|
||||||
|
var mysqldSafeFiles = []string{}
|
||||||
|
|
||||||
|
// read last path from cache file
|
||||||
|
var cacheFile = Tea.Root + "/data/mysql-path.cache"
|
||||||
|
cacheData, err := os.ReadFile(cacheFile)
|
||||||
|
if err == nil && len(cacheData) > 0 {
|
||||||
|
mysqldSafeFiles = append(mysqldSafeFiles, string(cacheData))
|
||||||
|
}
|
||||||
|
|
||||||
|
// from $PATH variable
|
||||||
|
exePath, lookErr := executils.LookPath("mysqld_safe")
|
||||||
|
if lookErr == nil && len(exePath) > 0 && !lists.ContainsString(mysqldSafeFiles, exePath) {
|
||||||
|
mysqldSafeFiles = append(mysqldSafeFiles, exePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// these installed by edge-boot or foolish-mysql
|
||||||
|
for _, path := range []string{
|
||||||
|
"/usr/local/mysql/bin/mysqld_safe",
|
||||||
|
"/usr/local/mysql8/bin/mysqld_safe",
|
||||||
|
} {
|
||||||
|
if !lists.ContainsString(mysqldSafeFiles, path) {
|
||||||
|
mysqldSafeFiles = append(mysqldSafeFiles, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mysqldSafeFile := range mysqldSafeFiles {
|
||||||
|
_, err := os.Stat(mysqldSafeFile)
|
||||||
|
if err == nil {
|
||||||
|
logs.Println("[API_NODE]try to start local mysql server from '" + mysqldSafeFile + "' ...")
|
||||||
|
var mysqlCmd = exec.Command(mysqldSafeFile)
|
||||||
|
_ = mysqlCmd.Start()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,3 +35,11 @@ func TestMySQLVersion(t *testing.T) {
|
|||||||
func TestMySQLVersionFrom8(t *testing.T) {
|
func TestMySQLVersionFrom8(t *testing.T) {
|
||||||
t.Log(dbutils.MySQLVersionFrom8())
|
t.Log(dbutils.MySQLVersionFrom8())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindMySQLPath(t *testing.T) {
|
||||||
|
t.Log(dbutils.FindMySQLPath())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStartLocalMySQL(t *testing.T) {
|
||||||
|
dbutils.StartLocalMySQL()
|
||||||
|
}
|
||||||
@@ -37,8 +37,8 @@ func (this *Unzip) Run() error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
for _, file := range reader.File {
|
for _, file := range reader.File {
|
||||||
info := file.FileInfo()
|
var info = file.FileInfo()
|
||||||
target := this.targetDir + "/" + file.Name
|
var target = this.targetDir + "/" + file.Name
|
||||||
|
|
||||||
// 目录
|
// 目录
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
@@ -62,7 +62,7 @@ func (this *Unzip) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 文件
|
// 文件
|
||||||
err := func(file *zip.File, target string) error {
|
err = func(file *zip.File, target string) error {
|
||||||
fileReader, err := file.Open()
|
fileReader, err := file.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -71,6 +71,10 @@ func (this *Unzip) Run() error {
|
|||||||
_ = fileReader.Close()
|
_ = fileReader.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// remove old
|
||||||
|
_ = os.Remove(target)
|
||||||
|
|
||||||
|
// create new
|
||||||
fileWriter, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, file.FileInfo().Mode())
|
fileWriter, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, file.FileInfo().Mode())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/iwind/gosock/pkg/gosock"
|
"github.com/iwind/gosock/pkg/gosock"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
@@ -294,6 +295,9 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err
|
|||||||
func (this *APINode) checkDB() error {
|
func (this *APINode) checkDB() error {
|
||||||
logs.Println("[API_NODE]checking database connection ...")
|
logs.Println("[API_NODE]checking database connection ...")
|
||||||
|
|
||||||
|
// lookup mysqld_safe process
|
||||||
|
go dbutils.FindMySQLPathAndRemember()
|
||||||
|
|
||||||
db, err := dbs.Default()
|
db, err := dbs.Default()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -310,13 +314,7 @@ func (this *APINode) checkDB() error {
|
|||||||
if strings.Contains(err.Error(), "connection refused") {
|
if strings.Contains(err.Error(), "connection refused") {
|
||||||
config, _ := db.Config()
|
config, _ := db.Config()
|
||||||
if config != nil && (strings.Contains(config.Dsn, "tcp(127.0.0.1:") || strings.Contains(config.Dsn, "tcp(localhost:")) && os.Getgid() == 0 /** ROOT 用户 **/ {
|
if config != nil && (strings.Contains(config.Dsn, "tcp(127.0.0.1:") || strings.Contains(config.Dsn, "tcp(localhost:")) && os.Getgid() == 0 /** ROOT 用户 **/ {
|
||||||
var mysqldSafeFile = "/usr/local/mysql/bin/mysqld_safe"
|
dbutils.StartLocalMySQL()
|
||||||
_, err = os.Stat(mysqldSafeFile)
|
|
||||||
if err == nil {
|
|
||||||
logs.Println("[API_NODE]try to start local mysql server from '" + mysqldSafeFile + "' ...")
|
|
||||||
var mysqlCmd = exec.Command(mysqldSafeFile)
|
|
||||||
_ = mysqlCmd.Start()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -832,7 +830,12 @@ func (this *APINode) unaryInterceptor(ctx context.Context, req any, info *grpc.U
|
|||||||
}
|
}
|
||||||
result, err := handler(ctx, req)
|
result, err := handler(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.New("'" + info.FullMethod + "()' says: " + err.Error())
|
statusErr, ok := status.FromError(err)
|
||||||
|
if ok {
|
||||||
|
err = status.Error(statusErr.Code(), "'"+info.FullMethod+"()' says: "+err.Error())
|
||||||
|
} else {
|
||||||
|
err = errors.New("'" + info.FullMethod + "()' says: " + err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ func (this *AdminService) FindAllAdminModules(ctx context.Context, req *pb.FindA
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := []*pb.AdminModuleList{}
|
var result = []*pb.AdminModuleList{}
|
||||||
for _, admin := range admins {
|
for _, admin := range admins {
|
||||||
modules := []*systemconfigs.AdminModule{}
|
modules := []*systemconfigs.AdminModule{}
|
||||||
if len(admin.Modules) > 0 {
|
if len(admin.Modules) > 0 {
|
||||||
@@ -292,7 +292,7 @@ func (this *AdminService) FindAllAdminModules(ctx context.Context, req *pb.FindA
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pbModules := []*pb.AdminModule{}
|
var pbModules = []*pb.AdminModule{}
|
||||||
for _, module := range modules {
|
for _, module := range modules {
|
||||||
pbModules = append(pbModules, &pb.AdminModule{
|
pbModules = append(pbModules, &pb.AdminModule{
|
||||||
AllowAll: module.AllowAll,
|
AllowAll: module.AllowAll,
|
||||||
@@ -301,11 +301,12 @@ func (this *AdminService) FindAllAdminModules(ctx context.Context, req *pb.FindA
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
list := &pb.AdminModuleList{
|
var list = &pb.AdminModuleList{
|
||||||
AdminId: int64(admin.Id),
|
AdminId: int64(admin.Id),
|
||||||
IsSuper: admin.IsSuper,
|
IsSuper: admin.IsSuper,
|
||||||
Fullname: admin.Fullname,
|
Fullname: admin.Fullname,
|
||||||
Theme: admin.Theme,
|
Theme: admin.Theme,
|
||||||
|
Lang: admin.Lang,
|
||||||
Modules: pbModules,
|
Modules: pbModules,
|
||||||
}
|
}
|
||||||
result = append(result, list)
|
result = append(result, list)
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ func (this *APINodeService) FindEnabledAPINode(ctx context.Context, req *pb.Find
|
|||||||
|
|
||||||
// FindCurrentAPINodeVersion 获取当前API节点的版本
|
// FindCurrentAPINodeVersion 获取当前API节点的版本
|
||||||
func (this *APINodeService) FindCurrentAPINodeVersion(ctx context.Context, req *pb.FindCurrentAPINodeVersionRequest) (*pb.FindCurrentAPINodeVersionResponse, error) {
|
func (this *APINodeService) FindCurrentAPINodeVersion(ctx context.Context, req *pb.FindCurrentAPINodeVersionRequest) (*pb.FindCurrentAPINodeVersionResponse, error) {
|
||||||
_, _, _, err := rpcutils.ValidateRequest(ctx)
|
role, _, _, err := rpcutils.ValidateRequest(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -249,6 +249,7 @@ func (this *APINodeService) FindCurrentAPINodeVersion(ctx context.Context, req *
|
|||||||
Version: teaconst.Version,
|
Version: teaconst.Version,
|
||||||
Os: runtime.GOOS,
|
Os: runtime.GOOS,
|
||||||
Arch: runtime.GOARCH,
|
Arch: runtime.GOARCH,
|
||||||
|
Role: role,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import (
|
|||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BaseService struct {
|
type BaseService struct {
|
||||||
@@ -229,7 +231,7 @@ func (this *BaseService) PermissionError() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *BaseService) NotImplementedYet() error {
|
func (this *BaseService) NotImplementedYet() error {
|
||||||
return errors.New("not implemented yet")
|
return status.Error(codes.Unimplemented, "not implemented yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NullTx 空的数据库事务
|
// NullTx 空的数据库事务
|
||||||
|
|||||||
@@ -303,7 +303,24 @@ func (this *DNSDomainService) SyncDNSDomainData(ctx context.Context, req *pb.Syn
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return this.syncClusterDNS(req)
|
|
||||||
|
var latestVersion = dns.SharedDNSTaskDAO.GenerateVersion()
|
||||||
|
|
||||||
|
resp, err := this.syncClusterDNS(req)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记集群所有任务已完成
|
||||||
|
if req.NodeClusterId > 0 && resp != nil && resp.IsOk {
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = dns.SharedDNSTaskDAO.UpdateClusterDNSTasksDone(tx, req.NodeClusterId, latestVersion)
|
||||||
|
if err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllDNSDomainRoutes 查看支持的线路
|
// FindAllDNSDomainRoutes 查看支持的线路
|
||||||
|
|||||||
@@ -117,3 +117,19 @@ func (this *DNSTaskService) DeleteDNSTask(ctx context.Context, req *pb.DeleteDNS
|
|||||||
}
|
}
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllDNSTasks 删除所有同步任务
|
||||||
|
func (this *DNSTaskService) DeleteAllDNSTasks(ctx context.Context, req *pb.DeleteAllDNSTasksRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = dns.SharedDNSTaskDAO.DeleteAllDNSTasks(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ func (this *HTTPCachePolicyService) CreateHTTPCachePolicy(ctx context.Context, r
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
policyId, err := models.SharedHTTPCachePolicyDAO.CreateCachePolicy(tx, req.IsOn, req.Name, req.Description, req.CapacityJSON, req.MaxKeys, req.MaxSizeJSON, req.Type, req.OptionsJSON, req.SyncCompressionCache)
|
policyId, err := models.SharedHTTPCachePolicyDAO.CreateCachePolicy(tx, req.IsOn, req.Name, req.Description, req.CapacityJSON, req.MaxSizeJSON, req.Type, req.OptionsJSON, req.SyncCompressionCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ func (this *HTTPCachePolicyService) UpdateHTTPCachePolicy(ctx context.Context, r
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedHTTPCachePolicyDAO.UpdateCachePolicy(tx, req.HttpCachePolicyId, req.IsOn, req.Name, req.Description, req.CapacityJSON, req.MaxKeys, req.MaxSizeJSON, req.Type, req.OptionsJSON, req.SyncCompressionCache)
|
err = models.SharedHTTPCachePolicyDAO.UpdateCachePolicy(tx, req.HttpCachePolicyId, req.IsOn, req.Name, req.Description, req.CapacityJSON, req.MaxSizeJSON, req.Type, req.OptionsJSON, req.SyncCompressionCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,11 @@ package services
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,6 +25,34 @@ func (this *HTTPPageService) CreateHTTPPage(ctx context.Context, req *pb.CreateH
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
// validate
|
||||||
|
const maxURLLength = 512
|
||||||
|
const maxBodyLength = 32 * 1024
|
||||||
|
|
||||||
|
switch req.BodyType {
|
||||||
|
case shared.BodyTypeURL:
|
||||||
|
if len(req.Url) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if !regexputils.HTTPProtocol.MatchString(req.Url) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
req.Body = ""
|
||||||
|
}
|
||||||
|
case shared.BodyTypeHTML:
|
||||||
|
if len(req.Body) > maxBodyLength {
|
||||||
|
return nil, errors.New("'body' too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Url) > maxURLLength { // we keep short url for user experience
|
||||||
|
req.Url = ""
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, errors.New("invalid 'bodyType': " + req.BodyType)
|
||||||
|
}
|
||||||
|
|
||||||
pageId, err := models.SharedHTTPPageDAO.CreatePage(tx, userId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
pageId, err := models.SharedHTTPPageDAO.CreatePage(tx, userId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -46,6 +77,34 @@ func (this *HTTPPageService) UpdateHTTPPage(ctx context.Context, req *pb.UpdateH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validate
|
||||||
|
const maxURLLength = 512
|
||||||
|
const maxBodyLength = 32 * 1024
|
||||||
|
|
||||||
|
switch req.BodyType {
|
||||||
|
case shared.BodyTypeURL:
|
||||||
|
if len(req.Url) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if !regexputils.HTTPProtocol.MatchString(req.Url) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
req.Body = ""
|
||||||
|
}
|
||||||
|
case shared.BodyTypeHTML:
|
||||||
|
if len(req.Body) > maxBodyLength {
|
||||||
|
return nil, errors.New("'body' too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Url) > maxURLLength { // we keep short url for user experience
|
||||||
|
req.Url = ""
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, errors.New("invalid 'bodyType': " + req.BodyType)
|
||||||
|
}
|
||||||
|
|
||||||
err = models.SharedHTTPPageDAO.UpdatePage(tx, req.HttpPageId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
err = models.SharedHTTPPageDAO.UpdatePage(tx, req.HttpPageId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ type HTTPRewriteRuleService struct {
|
|||||||
// CreateHTTPRewriteRule 创建重写规则
|
// CreateHTTPRewriteRule 创建重写规则
|
||||||
func (this *HTTPRewriteRuleService) CreateHTTPRewriteRule(ctx context.Context, req *pb.CreateHTTPRewriteRuleRequest) (*pb.CreateHTTPRewriteRuleResponse, error) {
|
func (this *HTTPRewriteRuleService) CreateHTTPRewriteRule(ctx context.Context, req *pb.CreateHTTPRewriteRuleRequest) (*pb.CreateHTTPRewriteRuleResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
rewriteRuleId, err := models.SharedHTTPRewriteRuleDAO.CreateRewriteRule(tx, req.Pattern, req.Replace, req.Mode, types.Int(req.RedirectStatus), req.IsBreak, req.ProxyHost, req.WithQuery, req.IsOn, req.CondsJSON)
|
rewriteRuleId, err := models.SharedHTTPRewriteRuleDAO.CreateRewriteRule(tx, userId, req.Pattern, req.Replace, req.Mode, types.Int(req.RedirectStatus), req.IsBreak, req.ProxyHost, req.WithQuery, req.IsOn, req.CondsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -33,12 +33,18 @@ func (this *HTTPRewriteRuleService) CreateHTTPRewriteRule(ctx context.Context, r
|
|||||||
// UpdateHTTPRewriteRule 修改重写规则
|
// UpdateHTTPRewriteRule 修改重写规则
|
||||||
func (this *HTTPRewriteRuleService) UpdateHTTPRewriteRule(ctx context.Context, req *pb.UpdateHTTPRewriteRuleRequest) (*pb.RPCSuccess, error) {
|
func (this *HTTPRewriteRuleService) UpdateHTTPRewriteRule(ctx context.Context, req *pb.UpdateHTTPRewriteRuleRequest) (*pb.RPCSuccess, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
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.SharedHTTPRewriteRuleDAO.CheckUserRewriteRule(tx, userId, req.RewriteRuleId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = models.SharedHTTPRewriteRuleDAO.UpdateRewriteRule(tx, req.RewriteRuleId, req.Pattern, req.Replace, req.Mode, types.Int(req.RedirectStatus), req.IsBreak, req.ProxyHost, req.WithQuery, req.IsOn, req.CondsJSON)
|
err = models.SharedHTTPRewriteRuleDAO.UpdateRewriteRule(tx, req.RewriteRuleId, req.Pattern, req.Replace, req.Mode, types.Int(req.RedirectStatus), req.IsBreak, req.ProxyHost, req.WithQuery, req.IsOn, req.CondsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,6 +111,8 @@ func (this *HTTPWebService) UpdateHTTPWeb(ctx context.Context, req *pb.UpdateHTT
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req.RootJSON = []byte("{}") // 为了安全
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
@@ -139,7 +143,60 @@ func (this *HTTPWebService) UpdateHTTPWebCompression(ctx context.Context, req *p
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedHTTPWebDAO.UpdateWebCompression(tx, req.HttpWebId, req.CompressionJSON)
|
if len(req.CompressionJSON) == 0 {
|
||||||
|
return nil, errors.New("'compressionJSON' should not be empty")
|
||||||
|
}
|
||||||
|
var compressionConfig = &serverconfigs.HTTPCompressionConfig{}
|
||||||
|
err = json.Unmarshal(req.CompressionJSON, compressionConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = compressionConfig.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedHTTPWebDAO.UpdateWebCompression(tx, req.HttpWebId, compressionConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateHTTPWebOptimization 修改页面优化配置
|
||||||
|
func (this *HTTPWebService) UpdateHTTPWebOptimization(ctx context.Context, req *pb.UpdateHTTPWebOptimizationRequest) (*pb.RPCSuccess, error) {
|
||||||
|
// 校验请求
|
||||||
|
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if userId > 0 {
|
||||||
|
// 检查用户权限
|
||||||
|
err = models.SharedHTTPWebDAO.CheckUserWeb(nil, userId, req.HttpWebId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
if len(req.OptimizationJSON) == 0 {
|
||||||
|
return nil, errors.New("invalid 'optimizationJSON'")
|
||||||
|
}
|
||||||
|
var optimizationConfig = serverconfigs.NewHTTPPageOptimizationConfig()
|
||||||
|
err = json.Unmarshal(req.OptimizationJSON, optimizationConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = optimizationConfig.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedHTTPWebDAO.UpdateWebOptimization(tx, req.HttpWebId, optimizationConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -292,8 +349,53 @@ func (this *HTTPWebService) UpdateHTTPWebShutdown(ctx context.Context, req *pb.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
var newShutdownJSON = req.ShutdownJSON
|
||||||
|
if len(req.ShutdownJSON) > 0 {
|
||||||
|
const maxURLLength = 512
|
||||||
|
const maxBodyLength = 32 * 1024
|
||||||
|
|
||||||
err = models.SharedHTTPWebDAO.UpdateWebShutdown(tx, req.HttpWebId, req.ShutdownJSON)
|
var shutdownConfig = &serverconfigs.HTTPShutdownConfig{}
|
||||||
|
err = json.Unmarshal(req.ShutdownJSON, shutdownConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = shutdownConfig.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("validate config failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
switch shutdownConfig.BodyType {
|
||||||
|
case shared.BodyTypeURL:
|
||||||
|
if len(shutdownConfig.URL) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if !regexputils.HTTPProtocol.MatchString(shutdownConfig.URL) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(shutdownConfig.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
shutdownConfig.Body = ""
|
||||||
|
}
|
||||||
|
case shared.BodyTypeHTML:
|
||||||
|
if len(shutdownConfig.Body) > maxBodyLength {
|
||||||
|
return nil, errors.New("'body' too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(shutdownConfig.URL) > maxURLLength { // we keep short url for user experience
|
||||||
|
shutdownConfig.URL = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, errors.New("invalid 'bodyType': " + shutdownConfig.BodyType)
|
||||||
|
}
|
||||||
|
|
||||||
|
newShutdownJSON, err = json.Marshal(shutdownConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedHTTPWebDAO.UpdateWebShutdown(tx, req.HttpWebId, newShutdownJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -319,14 +421,23 @@ func (this *HTTPWebService) UpdateHTTPWebPages(ctx context.Context, req *pb.Upda
|
|||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
// 检查配置
|
// 检查配置
|
||||||
var pages = []*serverconfigs.HTTPPageConfig{}
|
|
||||||
err = json.Unmarshal(req.PagesJSON, &pages)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("decode 'pages' failed: " + err.Error())
|
|
||||||
}
|
|
||||||
var newPages = []*serverconfigs.HTTPPageConfig{}
|
var newPages = []*serverconfigs.HTTPPageConfig{}
|
||||||
for _, page := range pages {
|
if len(req.PagesJSON) > 0 {
|
||||||
newPages = append(newPages, &serverconfigs.HTTPPageConfig{Id: page.Id})
|
var pages = []*serverconfigs.HTTPPageConfig{}
|
||||||
|
err = json.Unmarshal(req.PagesJSON, &pages)
|
||||||
|
|
||||||
|
for _, page := range pages {
|
||||||
|
err = page.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("validate page failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset not needed fields, keep "id" reference only
|
||||||
|
page.URL = ""
|
||||||
|
page.Body = ""
|
||||||
|
|
||||||
|
newPages = append(newPages, &serverconfigs.HTTPPageConfig{Id: page.Id})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
newPagesJSON, err := json.Marshal(newPages)
|
newPagesJSON, err := json.Marshal(newPages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ func (this *IPLibraryFileService) CheckCountriesWithIPLibraryFileId(ctx context.
|
|||||||
}
|
}
|
||||||
for _, similarCountry := range similarCountries {
|
for _, similarCountry := range similarCountries {
|
||||||
pbMissingCountry.SimilarCountries = append(pbMissingCountry.SimilarCountries, &pb.RegionCountry{
|
pbMissingCountry.SimilarCountries = append(pbMissingCountry.SimilarCountries, &pb.RegionCountry{
|
||||||
Id: int64(similarCountry.Id),
|
Id: int64(similarCountry.ValueId),
|
||||||
Name: similarCountry.Name,
|
Name: similarCountry.Name,
|
||||||
DisplayName: similarCountry.DisplayName(),
|
DisplayName: similarCountry.DisplayName(),
|
||||||
})
|
})
|
||||||
@@ -391,7 +391,7 @@ func (this *IPLibraryFileService) CheckProvincesWithIPLibraryFileId(ctx context.
|
|||||||
|
|
||||||
for _, similarProvince := range similarProvinces {
|
for _, similarProvince := range similarProvinces {
|
||||||
pbMissingProvince.SimilarProvinces = append(pbMissingProvince.SimilarProvinces, &pb.RegionProvince{
|
pbMissingProvince.SimilarProvinces = append(pbMissingProvince.SimilarProvinces, &pb.RegionProvince{
|
||||||
Id: int64(similarProvince.Id),
|
Id: int64(similarProvince.ValueId),
|
||||||
Name: similarProvince.Name,
|
Name: similarProvince.Name,
|
||||||
DisplayName: similarProvince.DisplayName(),
|
DisplayName: similarProvince.DisplayName(),
|
||||||
})
|
})
|
||||||
@@ -482,7 +482,7 @@ func (this *IPLibraryFileService) CheckCitiesWithIPLibraryFileId(ctx context.Con
|
|||||||
|
|
||||||
for _, similarCity := range similarCities {
|
for _, similarCity := range similarCities {
|
||||||
pbMissingCity.SimilarCities = append(pbMissingCity.SimilarCities, &pb.RegionCity{
|
pbMissingCity.SimilarCities = append(pbMissingCity.SimilarCities, &pb.RegionCity{
|
||||||
Id: int64(similarCity.Id),
|
Id: int64(similarCity.ValueId),
|
||||||
Name: similarCity.Name,
|
Name: similarCity.Name,
|
||||||
DisplayName: similarCity.DisplayName(),
|
DisplayName: similarCity.DisplayName(),
|
||||||
})
|
})
|
||||||
@@ -597,7 +597,7 @@ func (this *IPLibraryFileService) CheckTownsWithIPLibraryFileId(ctx context.Cont
|
|||||||
|
|
||||||
for _, similarTown := range similarTowns {
|
for _, similarTown := range similarTowns {
|
||||||
pbMissingTown.SimilarTowns = append(pbMissingTown.SimilarTowns, &pb.RegionTown{
|
pbMissingTown.SimilarTowns = append(pbMissingTown.SimilarTowns, &pb.RegionTown{
|
||||||
Id: int64(similarTown.Id),
|
Id: int64(similarTown.ValueId),
|
||||||
Name: similarTown.Name,
|
Name: similarTown.Name,
|
||||||
DisplayName: similarTown.DisplayName(),
|
DisplayName: similarTown.DisplayName(),
|
||||||
})
|
})
|
||||||
@@ -654,7 +654,7 @@ func (this *IPLibraryFileService) CheckProvidersWithIPLibraryFileId(ctx context.
|
|||||||
}
|
}
|
||||||
for _, similarProvider := range similarProviders {
|
for _, similarProvider := range similarProviders {
|
||||||
pbMissingProvider.SimilarProviders = append(pbMissingProvider.SimilarProviders, &pb.RegionProvider{
|
pbMissingProvider.SimilarProviders = append(pbMissingProvider.SimilarProviders, &pb.RegionProvider{
|
||||||
Id: int64(similarProvider.Id),
|
Id: int64(similarProvider.ValueId),
|
||||||
Name: similarProvider.Name,
|
Name: similarProvider.Name,
|
||||||
DisplayName: similarProvider.DisplayName(),
|
DisplayName: similarProvider.DisplayName(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/langs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,7 +24,16 @@ func (this *LogService) CreateLog(ctx context.Context, req *pb.CreateLogRequest)
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedLogDAO.CreateLog(tx, userType, userId, req.Level, req.Description, req.Action, req.Ip)
|
// i18n
|
||||||
|
var langMessageArgs = []any{}
|
||||||
|
if len(req.LangMessageArgsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.LangMessageArgsJSON, &langMessageArgs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedLogDAO.CreateLog(tx, userType, userId, req.Level, req.Description, req.Action, req.Ip, langs.MessageCode(req.LangMessageCode), langMessageArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2016,7 +2016,7 @@ func (this *NodeService) FindNodeGlobalServerConfig(ctx context.Context, req *pb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = serverconfigs.DefaultGlobalServerConfig()
|
config = serverconfigs.NewGlobalServerConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
configJSON, err := json.Marshal(config)
|
configJSON, err := json.Marshal(config)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (this *NodeClusterService) CreateNodeCluster(ctx context.Context, req *pb.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 全局服务配置
|
// 全局服务配置
|
||||||
var serverGlobalConfig = serverconfigs.DefaultGlobalServerConfig()
|
var serverGlobalConfig = serverconfigs.NewGlobalServerConfig()
|
||||||
if len(req.GlobalServerConfigJSON) > 0 {
|
if len(req.GlobalServerConfigJSON) > 0 {
|
||||||
err = json.Unmarshal(req.GlobalServerConfigJSON, serverGlobalConfig)
|
err = json.Unmarshal(req.GlobalServerConfigJSON, serverGlobalConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1130,15 +1130,15 @@ func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UAM
|
// UAM
|
||||||
|
var uamPolicy = nodeconfigs.NewUAMPolicy()
|
||||||
if models.IsNotNull(cluster.Uam) {
|
if models.IsNotNull(cluster.Uam) {
|
||||||
var uamPolicy = &nodeconfigs.UAMPolicy{}
|
|
||||||
err = json.Unmarshal(cluster.Uam, uamPolicy)
|
err = json.Unmarshal(cluster.Uam, uamPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result.UamIsOn = uamPolicy.IsOn
|
result.UamIsOn = uamPolicy.IsOn
|
||||||
} else {
|
} else {
|
||||||
result.UamIsOn = nodeconfigs.DefaultUAMPolicy.IsOn
|
result.UamIsOn = uamPolicy.IsOn
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTP CC
|
// HTTP CC
|
||||||
@@ -1180,6 +1180,16 @@ func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Con
|
|||||||
result.HasHTTPPagesPolicy = pagesPolicy.IsOn && len(pagesPolicy.Pages) > 0
|
result.HasHTTPPagesPolicy = pagesPolicy.IsOn && len(pagesPolicy.Pages) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HTTP/3
|
||||||
|
if models.IsNotNull(cluster.Http3) {
|
||||||
|
var http3Policy = nodeconfigs.NewHTTP3Policy()
|
||||||
|
err = json.Unmarshal(cluster.Http3, http3Policy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result.Http3IsOn = http3Policy.IsOn
|
||||||
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1282,7 +1292,7 @@ func (this *NodeClusterService) UpdateNodeClusterUAMPolicy(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var uamPolicy = &nodeconfigs.UAMPolicy{}
|
var uamPolicy = nodeconfigs.NewUAMPolicy()
|
||||||
err = json.Unmarshal(req.UamPolicyJSON, uamPolicy)
|
err = json.Unmarshal(req.UamPolicyJSON, uamPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1301,7 +1311,6 @@ func (this *NodeClusterService) UpdateNodeClusterUAMPolicy(ctx context.Context,
|
|||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FindEnabledNodeClusterHTTPCCPolicy 读取集群HTTP CC策略
|
// FindEnabledNodeClusterHTTPCCPolicy 读取集群HTTP CC策略
|
||||||
func (this *NodeClusterService) FindEnabledNodeClusterHTTPCCPolicy(ctx context.Context, req *pb.FindEnabledNodeClusterHTTPCCPolicyRequest) (*pb.FindEnabledNodeClusterHTTPCCPolicyResponse, error) {
|
func (this *NodeClusterService) FindEnabledNodeClusterHTTPCCPolicy(ctx context.Context, req *pb.FindEnabledNodeClusterHTTPCCPolicyRequest) (*pb.FindEnabledNodeClusterHTTPCCPolicyResponse, error) {
|
||||||
if !teaconst.IsPlus {
|
if !teaconst.IsPlus {
|
||||||
@@ -1435,7 +1444,7 @@ func (this *NodeClusterService) UpdateNodeClusterGlobalServerConfig(ctx context.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = serverconfigs.DefaultGlobalServerConfig()
|
var config = serverconfigs.NewGlobalServerConfig()
|
||||||
err = json.Unmarshal(req.GlobalServerConfigJSON, config)
|
err = json.Unmarshal(req.GlobalServerConfigJSON, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1502,3 +1511,33 @@ func (this *NodeClusterService) UpdateNodeClusterHTTPPagesPolicy(ctx context.Con
|
|||||||
|
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateNodeClusterHTTP3Policy 修改集群的HTTP3设置
|
||||||
|
func (this *NodeClusterService) UpdateNodeClusterHTTP3Policy(ctx context.Context, req *pb.UpdateNodeClusterHTTP3PolicyRequest) (*pb.RPCSuccess, error) {
|
||||||
|
if !teaconst.IsPlus {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var http3Policy = nodeconfigs.NewHTTP3Policy()
|
||||||
|
err = json.Unmarshal(req.Http3PolicyJSON, http3Policy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = http3Policy.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("validate http3 policy failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedNodeClusterDAO.UpdateClusterHTTP3Policy(tx, req.NodeClusterId, http3Policy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|||||||
13
internal/rpc/services/service_node_cluster_ext.go
Normal file
13
internal/rpc/services/service_node_cluster_ext.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *NodeClusterService) FindNodeClusterHTTP3Policy(ctx context.Context, req *pb.FindNodeClusterHTTP3PolicyRequest) (*pb.FindNodeClusterHTTP3PolicyResponse, error) {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
@@ -16,6 +16,10 @@ func (this *NodeService) FindNodeHTTPCCPolicies(ctx context.Context, req *pb.Fin
|
|||||||
return nil, this.NotImplementedYet()
|
return nil, this.NotImplementedYet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *NodeService) FindNodeHTTP3Policies(ctx context.Context, req *pb.FindNodeHTTP3PoliciesRequest) (*pb.FindNodeHTTP3PoliciesResponse, error) {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
|
|
||||||
func (this *NodeService) FindNodeHTTPPagesPolicies(ctx context.Context, req *pb.FindNodeHTTPPagesPoliciesRequest) (*pb.FindNodeHTTPPagesPoliciesResponse, error) {
|
func (this *NodeService) FindNodeHTTPPagesPolicies(ctx context.Context, req *pb.FindNodeHTTPPagesPoliciesRequest) (*pb.FindNodeHTTPPagesPoliciesResponse, error) {
|
||||||
return nil, this.NotImplementedYet()
|
return nil, this.NotImplementedYet()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,6 +216,22 @@ func (this *NodeTaskService) DeleteNodeTasks(ctx context.Context, req *pb.Delete
|
|||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllNodeTasks 删除所有任务
|
||||||
|
func (this *NodeTaskService) DeleteAllNodeTasks(ctx context.Context, req *pb.DeleteAllNodeTasksRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedNodeTaskDAO.DeleteAllNodeTasks(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
// CountDoingNodeTasks 计算正在执行的任务数量
|
// CountDoingNodeTasks 计算正在执行的任务数量
|
||||||
func (this *NodeTaskService) CountDoingNodeTasks(ctx context.Context, req *pb.CountDoingNodeTasksRequest) (*pb.RPCCountResponse, error) {
|
func (this *NodeTaskService) CountDoingNodeTasks(ctx context.Context, req *pb.CountDoingNodeTasksRequest) (*pb.RPCCountResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx)
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ossconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
@@ -23,15 +24,26 @@ func (this *OriginService) CreateOrigin(ctx context.Context, req *pb.CreateOrigi
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 源站地址设置
|
||||||
if req.Addr == nil {
|
if req.Addr == nil {
|
||||||
return nil, errors.New("'addr' can not be nil")
|
return nil, errors.New("'addr' can not be nil")
|
||||||
}
|
}
|
||||||
addrMap := maps.Map{
|
var addrMap = maps.Map{
|
||||||
"protocol": req.Addr.Protocol,
|
"protocol": req.Addr.Protocol,
|
||||||
"portRange": req.Addr.PortRange,
|
"portRange": req.Addr.PortRange,
|
||||||
"host": req.Addr.Host,
|
"host": req.Addr.Host,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OSS设置
|
||||||
|
var ossConfig *ossconfigs.OSSConfig
|
||||||
|
if len(req.OssJSON) > 0 {
|
||||||
|
ossConfig = ossconfigs.NewOSSConfig()
|
||||||
|
err = json.Unmarshal(req.OssJSON, ossConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
// 校验参数
|
// 校验参数
|
||||||
@@ -72,7 +84,7 @@ func (this *OriginService) CreateOrigin(ctx context.Context, req *pb.CreateOrigi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, userId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort)
|
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, userId, req.Name, addrMap.AsJSON(), ossConfig, req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort, req.Http2Enabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -95,6 +107,8 @@ func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOrigi
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 源站地址设置
|
||||||
if req.Addr == nil {
|
if req.Addr == nil {
|
||||||
return nil, errors.New("'addr' can not be nil")
|
return nil, errors.New("'addr' can not be nil")
|
||||||
}
|
}
|
||||||
@@ -104,6 +118,16 @@ func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOrigi
|
|||||||
"host": req.Addr.Host,
|
"host": req.Addr.Host,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OSS设置
|
||||||
|
var ossConfig *ossconfigs.OSSConfig
|
||||||
|
if len(req.OssJSON) > 0 {
|
||||||
|
ossConfig = ossconfigs.NewOSSConfig()
|
||||||
|
err = json.Unmarshal(req.OssJSON, ossConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 校验参数
|
// 校验参数
|
||||||
var connTimeout = &shared.TimeDuration{}
|
var connTimeout = &shared.TimeDuration{}
|
||||||
if len(req.ConnTimeoutJSON) > 0 {
|
if len(req.ConnTimeoutJSON) > 0 {
|
||||||
@@ -142,7 +166,7 @@ func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOrigi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedOriginDAO.UpdateOrigin(tx, req.OriginId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort)
|
err = models.SharedOriginDAO.UpdateOrigin(tx, req.OriginId, req.Name, addrMap.AsJSON(), ossConfig, req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, certRef, req.Domains, req.Host, req.FollowPort, req.Http2Enabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -180,7 +204,7 @@ func (this *OriginService) FindEnabledOrigin(ctx context.Context, req *pb.FindEn
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &pb.Origin{
|
return &pb.FindEnabledOriginResponse{Origin: &pb.Origin{
|
||||||
Id: int64(origin.Id),
|
Id: int64(origin.Id),
|
||||||
IsOn: origin.IsOn,
|
IsOn: origin.IsOn,
|
||||||
Name: origin.Name,
|
Name: origin.Name,
|
||||||
@@ -189,10 +213,11 @@ func (this *OriginService) FindEnabledOrigin(ctx context.Context, req *pb.FindEn
|
|||||||
Host: addr.Host,
|
Host: addr.Host,
|
||||||
PortRange: addr.PortRange,
|
PortRange: addr.PortRange,
|
||||||
},
|
},
|
||||||
Description: origin.Description,
|
Description: origin.Description,
|
||||||
Domains: origin.DecodeDomains(),
|
Domains: origin.DecodeDomains(),
|
||||||
}
|
FollowPort: origin.FollowPort,
|
||||||
return &pb.FindEnabledOriginResponse{Origin: result}, nil
|
Http2Enabled: origin.Http2Enabled,
|
||||||
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindEnabledOriginConfig 查找源站配置
|
// FindEnabledOriginConfig 查找源站配置
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (this *RegionCityService) FindAllEnabledRegionCities(ctx context.Context, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbProvince = &pb.RegionProvince{
|
pbProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
DisplayName: province.DisplayName(),
|
DisplayName: province.DisplayName(),
|
||||||
@@ -57,7 +57,7 @@ func (this *RegionCityService) FindAllEnabledRegionCities(ctx context.Context, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbCities = append(pbCities, &pb.RegionCity{
|
pbCities = append(pbCities, &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
@@ -108,7 +108,7 @@ func (this *RegionCityService) FindAllRegionCities(ctx context.Context, req *pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbProvince = &pb.RegionProvince{
|
pbProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
@@ -118,7 +118,7 @@ func (this *RegionCityService) FindAllRegionCities(ctx context.Context, req *pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbCities = append(pbCities, &pb.RegionCity{
|
pbCities = append(pbCities, &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
@@ -155,7 +155,7 @@ func (this *RegionCityService) FindAllRegionCitiesWithRegionProvinceId(ctx conte
|
|||||||
var pbProvince = &pb.RegionProvince{Id: provinceId}
|
var pbProvince = &pb.RegionProvince{Id: provinceId}
|
||||||
|
|
||||||
pbCities = append(pbCities, &pb.RegionCity{
|
pbCities = append(pbCities, &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
@@ -192,7 +192,7 @@ func (this *RegionCityService) FindEnabledRegionCity(ctx context.Context, req *p
|
|||||||
|
|
||||||
return &pb.FindEnabledRegionCityResponse{
|
return &pb.FindEnabledRegionCityResponse{
|
||||||
RegionCity: &pb.RegionCity{
|
RegionCity: &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
@@ -223,7 +223,7 @@ func (this *RegionCityService) FindRegionCity(ctx context.Context, req *pb.FindR
|
|||||||
|
|
||||||
return &pb.FindRegionCityResponse{
|
return &pb.FindRegionCityResponse{
|
||||||
RegionCity: &pb.RegionCity{
|
RegionCity: &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
RegionProvinceId: int64(city.ProvinceId),
|
RegionProvinceId: int64(city.ProvinceId),
|
||||||
|
|||||||
@@ -40,13 +40,14 @@ func (this *RegionCountryService) FindAllEnabledRegionCountries(ctx context.Cont
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, &pb.RegionCountry{
|
result = append(result, &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.Name,
|
Name: country.Name,
|
||||||
Codes: country.DecodeCodes(),
|
Codes: country.DecodeCodes(),
|
||||||
Pinyin: pinyinStrings,
|
Pinyin: pinyinStrings,
|
||||||
CustomName: country.CustomName,
|
CustomName: country.CustomName,
|
||||||
CustomCodes: country.DecodeCustomCodes(),
|
CustomCodes: country.DecodeCustomCodes(),
|
||||||
DisplayName: country.DisplayName(),
|
DisplayName: country.DisplayName(),
|
||||||
|
IsCommon: country.IsCommon,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return &pb.FindAllEnabledRegionCountriesResponse{
|
return &pb.FindAllEnabledRegionCountriesResponse{
|
||||||
@@ -74,7 +75,7 @@ func (this *RegionCountryService) FindEnabledRegionCountry(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindEnabledRegionCountryResponse{RegionCountry: &pb.RegionCountry{
|
return &pb.FindEnabledRegionCountryResponse{RegionCountry: &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.Name,
|
Name: country.Name,
|
||||||
Codes: country.DecodeCodes(),
|
Codes: country.DecodeCodes(),
|
||||||
CustomName: country.CustomName,
|
CustomName: country.CustomName,
|
||||||
@@ -110,13 +111,14 @@ func (this *RegionCountryService) FindAllRegionCountries(ctx context.Context, re
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, &pb.RegionCountry{
|
result = append(result, &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.Name,
|
Name: country.Name,
|
||||||
Codes: country.DecodeCodes(),
|
Codes: country.DecodeCodes(),
|
||||||
Pinyin: pinyinStrings,
|
Pinyin: pinyinStrings,
|
||||||
CustomName: country.CustomName,
|
CustomName: country.CustomName,
|
||||||
CustomCodes: country.DecodeCustomCodes(),
|
CustomCodes: country.DecodeCustomCodes(),
|
||||||
DisplayName: country.DisplayName(),
|
DisplayName: country.DisplayName(),
|
||||||
|
IsCommon: country.IsCommon,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return &pb.FindAllRegionCountriesResponse{
|
return &pb.FindAllRegionCountriesResponse{
|
||||||
@@ -143,12 +145,13 @@ func (this *RegionCountryService) FindRegionCountry(ctx context.Context, req *pb
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindRegionCountryResponse{RegionCountry: &pb.RegionCountry{
|
return &pb.FindRegionCountryResponse{RegionCountry: &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.Name,
|
Name: country.Name,
|
||||||
Codes: country.DecodeCodes(),
|
Codes: country.DecodeCodes(),
|
||||||
CustomName: country.CustomName,
|
CustomName: country.CustomName,
|
||||||
CustomCodes: country.DecodeCustomCodes(),
|
CustomCodes: country.DecodeCustomCodes(),
|
||||||
DisplayName: country.DisplayName(),
|
DisplayName: country.DisplayName(),
|
||||||
|
IsCommon: country.IsCommon,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func (this *RegionProviderService) FindAllEnabledRegionProviders(ctx context.Con
|
|||||||
var pbProviders = []*pb.RegionProvider{}
|
var pbProviders = []*pb.RegionProvider{}
|
||||||
for _, provider := range providers {
|
for _, provider := range providers {
|
||||||
pbProviders = append(pbProviders, &pb.RegionProvider{
|
pbProviders = append(pbProviders, &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.Name,
|
Name: provider.Name,
|
||||||
Codes: provider.DecodeCodes(),
|
Codes: provider.DecodeCodes(),
|
||||||
CustomName: provider.CustomName,
|
CustomName: provider.CustomName,
|
||||||
@@ -65,7 +65,7 @@ func (this *RegionProviderService) FindEnabledRegionProvider(ctx context.Context
|
|||||||
|
|
||||||
return &pb.FindEnabledRegionProviderResponse{
|
return &pb.FindEnabledRegionProviderResponse{
|
||||||
RegionProvider: &pb.RegionProvider{
|
RegionProvider: &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.Name,
|
Name: provider.Name,
|
||||||
Codes: provider.DecodeCodes(),
|
Codes: provider.DecodeCodes(),
|
||||||
CustomName: provider.CustomName,
|
CustomName: provider.CustomName,
|
||||||
@@ -91,7 +91,7 @@ func (this *RegionProviderService) FindAllRegionProviders(ctx context.Context, r
|
|||||||
var pbProviders = []*pb.RegionProvider{}
|
var pbProviders = []*pb.RegionProvider{}
|
||||||
for _, provider := range providers {
|
for _, provider := range providers {
|
||||||
pbProviders = append(pbProviders, &pb.RegionProvider{
|
pbProviders = append(pbProviders, &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.Name,
|
Name: provider.Name,
|
||||||
Codes: provider.DecodeCodes(),
|
Codes: provider.DecodeCodes(),
|
||||||
CustomName: provider.CustomName,
|
CustomName: provider.CustomName,
|
||||||
@@ -125,7 +125,7 @@ func (this *RegionProviderService) FindRegionProvider(ctx context.Context, req *
|
|||||||
|
|
||||||
return &pb.FindRegionProviderResponse{
|
return &pb.FindRegionProviderResponse{
|
||||||
RegionProvider: &pb.RegionProvider{
|
RegionProvider: &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.Name,
|
Name: provider.Name,
|
||||||
Codes: provider.DecodeCodes(),
|
Codes: provider.DecodeCodes(),
|
||||||
CustomName: provider.CustomName,
|
CustomName: provider.CustomName,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func (this *RegionProvinceService) FindAllEnabledRegionProvincesWithCountryId(ct
|
|||||||
result := []*pb.RegionProvince{}
|
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.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
@@ -64,7 +64,7 @@ func (this *RegionProvinceService) FindEnabledRegionProvince(ctx context.Context
|
|||||||
|
|
||||||
return &pb.FindEnabledRegionProvinceResponse{
|
return &pb.FindEnabledRegionProvinceResponse{
|
||||||
RegionProvince: &pb.RegionProvince{
|
RegionProvince: &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
@@ -91,7 +91,7 @@ func (this *RegionProvinceService) FindAllRegionProvincesWithRegionCountryId(ctx
|
|||||||
var 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.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
@@ -125,7 +125,7 @@ func (this *RegionProvinceService) FindRegionProvince(ctx context.Context, req *
|
|||||||
|
|
||||||
return &pb.FindRegionProvinceResponse{
|
return &pb.FindRegionProvinceResponse{
|
||||||
RegionProvince: &pb.RegionProvince{
|
RegionProvince: &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.Name,
|
Name: province.Name,
|
||||||
Codes: province.DecodeCodes(),
|
Codes: province.DecodeCodes(),
|
||||||
CustomName: province.CustomName,
|
CustomName: province.CustomName,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func (this *RegionTownService) FindAllRegionTowns(ctx context.Context, req *pb.F
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbCity = &pb.RegionCity{
|
pbCity = &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.Name,
|
Name: city.Name,
|
||||||
Codes: city.DecodeCodes(),
|
Codes: city.DecodeCodes(),
|
||||||
CustomName: city.CustomName,
|
CustomName: city.CustomName,
|
||||||
@@ -58,7 +58,7 @@ func (this *RegionTownService) FindAllRegionTowns(ctx context.Context, req *pb.F
|
|||||||
}
|
}
|
||||||
|
|
||||||
pbTowns = append(pbTowns, &pb.RegionTown{
|
pbTowns = append(pbTowns, &pb.RegionTown{
|
||||||
Id: int64(town.Id),
|
Id: int64(town.ValueId),
|
||||||
Name: town.Name,
|
Name: town.Name,
|
||||||
Codes: town.DecodeCodes(),
|
Codes: town.DecodeCodes(),
|
||||||
RegionCityId: int64(town.CityId),
|
RegionCityId: int64(town.CityId),
|
||||||
@@ -95,7 +95,7 @@ func (this *RegionTownService) FindAllRegionTownsWithRegionCityId(ctx context.Co
|
|||||||
var pbCity = &pb.RegionCity{Id: cityId}
|
var pbCity = &pb.RegionCity{Id: cityId}
|
||||||
|
|
||||||
pbTowns = append(pbTowns, &pb.RegionTown{
|
pbTowns = append(pbTowns, &pb.RegionTown{
|
||||||
Id: int64(town.Id),
|
Id: int64(town.ValueId),
|
||||||
Name: town.Name,
|
Name: town.Name,
|
||||||
Codes: town.DecodeCodes(),
|
Codes: town.DecodeCodes(),
|
||||||
RegionCityId: int64(town.CityId),
|
RegionCityId: int64(town.CityId),
|
||||||
@@ -131,7 +131,7 @@ func (this *RegionTownService) FindRegionTown(ctx context.Context, req *pb.FindR
|
|||||||
|
|
||||||
return &pb.FindRegionTownResponse{
|
return &pb.FindRegionTownResponse{
|
||||||
RegionTown: &pb.RegionTown{
|
RegionTown: &pb.RegionTown{
|
||||||
Id: int64(town.Id),
|
Id: int64(town.ValueId),
|
||||||
Name: town.Name,
|
Name: town.Name,
|
||||||
Codes: town.DecodeCodes(),
|
Codes: town.DecodeCodes(),
|
||||||
RegionCityId: int64(town.CityId),
|
RegionCityId: int64(town.CityId),
|
||||||
|
|||||||
@@ -9,13 +9,17 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models/clients"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/domainutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
"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"
|
||||||
|
"net"
|
||||||
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -184,6 +188,505 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
|
|||||||
return &pb.CreateServerResponse{ServerId: serverId}, nil
|
return &pb.CreateServerResponse{ServerId: serverId}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateBasicHTTPServer 快速创建基本的HTTP网站
|
||||||
|
func (this *ServerService) CreateBasicHTTPServer(ctx context.Context, req *pb.CreateBasicHTTPServerRequest) (*pb.CreateBasicHTTPServerResponse, error) {
|
||||||
|
adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 集群
|
||||||
|
var tx = this.NullTx()
|
||||||
|
if userId > 0 {
|
||||||
|
req.UserId = userId
|
||||||
|
|
||||||
|
nodeClusterId, err := models.SharedUserDAO.FindUserClusterId(tx, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.NodeClusterId = nodeClusterId
|
||||||
|
} else if adminId > 0 && req.UserId > 0 && req.NodeClusterId <= 0 {
|
||||||
|
// check user
|
||||||
|
existUser, err := models.SharedUserDAO.Exist(tx, req.UserId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !existUser {
|
||||||
|
return nil, errors.New("user id '" + types.String(req.UserId) + "' not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeClusterId, err := models.SharedUserDAO.FindUserClusterId(tx, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.NodeClusterId = nodeClusterId
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.NodeClusterId <= 0 {
|
||||||
|
return nil, errors.New("invalid 'nodeClusterId'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Domains) == 0 {
|
||||||
|
return nil, errors.New("'domains' should not be empty")
|
||||||
|
}
|
||||||
|
var serverNames = []*serverconfigs.ServerNameConfig{}
|
||||||
|
for _, domain := range req.Domains {
|
||||||
|
domain = strings.ToLower(domain)
|
||||||
|
if !domainutils.ValidateDomainFormat(domain) {
|
||||||
|
return nil, errors.New("invalid domain format '" + domain + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查域名是否已存在
|
||||||
|
existServerName, err := models.SharedServerDAO.ExistServerNameInCluster(tx, req.NodeClusterId, domain, 0, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if existServerName {
|
||||||
|
return nil, errors.New("domain '" + domain + "' already created by other server")
|
||||||
|
}
|
||||||
|
|
||||||
|
serverNames = append(serverNames, &serverconfigs.ServerNameConfig{Name: domain})
|
||||||
|
}
|
||||||
|
serverNamesJSON, err := json.Marshal(serverNames)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("encode 'serverNames' failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否需要审核
|
||||||
|
var isAuditing = false
|
||||||
|
var auditingServerNamesJSON = []byte("[]")
|
||||||
|
if userId > 0 {
|
||||||
|
// 如果域名不为空的时候需要审核
|
||||||
|
if len(serverNamesJSON) > 0 && string(serverNamesJSON) != "[]" {
|
||||||
|
globalConfig, err := models.SharedSysSettingDAO.ReadGlobalConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if globalConfig != nil && globalConfig.HTTPAll.DomainAuditingIsOn {
|
||||||
|
isAuditing = true
|
||||||
|
serverNamesJSON = []byte("[]")
|
||||||
|
auditingServerNamesJSON = serverNamesJSON
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTP
|
||||||
|
var httpConfig = &serverconfigs.HTTPProtocolConfig{
|
||||||
|
BaseProtocol: serverconfigs.BaseProtocol{
|
||||||
|
IsOn: true,
|
||||||
|
Listen: []*serverconfigs.NetworkAddressConfig{
|
||||||
|
{
|
||||||
|
Protocol: "http",
|
||||||
|
PortRange: "80",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
httpJSON, err := json.Marshal(httpConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTTPS
|
||||||
|
var certRefs = []*sslconfigs.SSLCertRef{}
|
||||||
|
for _, certId := range req.SslCertIds {
|
||||||
|
// 检查所有权
|
||||||
|
if userId > 0 {
|
||||||
|
err = models.SharedSSLCertDAO.CheckUserCert(tx, certId, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("check cert permission failed: " + err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
existCert, err := models.SharedSSLCertDAO.Exist(tx, certId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !existCert {
|
||||||
|
return nil, errors.New("cert '" + types.String(certId) + "' not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
certRefs = append(certRefs, &sslconfigs.SSLCertRef{
|
||||||
|
IsOn: true,
|
||||||
|
CertId: certId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
certRefsJSON, err := json.Marshal(certRefs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sslPolicyId, err := models.SharedSSLPolicyDAO.CreatePolicy(tx, adminId, req.UserId, false, false, "TLS 1.0", certRefsJSON, nil, false, 0, nil, false, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpsConfig = &serverconfigs.HTTPSProtocolConfig{
|
||||||
|
BaseProtocol: serverconfigs.BaseProtocol{
|
||||||
|
IsOn: true,
|
||||||
|
Listen: []*serverconfigs.NetworkAddressConfig{
|
||||||
|
{
|
||||||
|
Protocol: "https",
|
||||||
|
PortRange: "443",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SSLPolicyRef: &sslconfigs.SSLPolicyRef{
|
||||||
|
IsOn: true,
|
||||||
|
SSLPolicyId: sslPolicyId,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
httpsJSON, err := json.Marshal(httpsConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse Proxy
|
||||||
|
var reverseProxyScheduleConfig = &serverconfigs.SchedulingConfig{
|
||||||
|
Code: "random",
|
||||||
|
Options: nil,
|
||||||
|
}
|
||||||
|
reverseProxyScheduleJSON, err := json.Marshal(reverseProxyScheduleConfig)
|
||||||
|
|
||||||
|
var primaryOrigins = []*serverconfigs.OriginRef{}
|
||||||
|
for _, originAddr := range req.OriginAddrs {
|
||||||
|
u, err := url.Parse(originAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("parse origin address '" + originAddr + "' failed: " + err.Error())
|
||||||
|
}
|
||||||
|
if len(u.Scheme) == 0 || (u.Scheme != "http" && u.Scheme != "https" /** 特意不支持大写形式 **/) {
|
||||||
|
return nil, errors.New("invalid scheme in origin address '" + originAddr + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(u.Host) == 0 {
|
||||||
|
return nil, errors.New("invalid host address '" + originAddr + "', contains no host")
|
||||||
|
}
|
||||||
|
|
||||||
|
host, port, err := net.SplitHostPort(u.Host)
|
||||||
|
if err != nil {
|
||||||
|
err = nil // ignore error
|
||||||
|
|
||||||
|
if domainutils.ValidateDomainFormat(u.Host) { // host with no port
|
||||||
|
host = u.Host
|
||||||
|
port = ""
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("invalid host address '" + originAddr + "', invalid host format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(port) == 0 {
|
||||||
|
switch u.Scheme {
|
||||||
|
case "http":
|
||||||
|
port = "80"
|
||||||
|
case "https":
|
||||||
|
port = "443"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var addr = &serverconfigs.NetworkAddressConfig{
|
||||||
|
Protocol: serverconfigs.Protocol(u.Scheme),
|
||||||
|
Host: host,
|
||||||
|
PortRange: port,
|
||||||
|
}
|
||||||
|
addrJSON, err := json.Marshal(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, req.UserId, "", addrJSON, nil, "", 10, true, nil, nil, nil, 0, 0, nil, nil, u.Host, false, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
primaryOrigins = append(primaryOrigins, &serverconfigs.OriginRef{
|
||||||
|
IsOn: true,
|
||||||
|
OriginId: originId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
primaryOriginsJSON, err := json.Marshal(primaryOrigins)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reverseProxyId, err := models.SharedReverseProxyDAO.CreateReverseProxy(tx, adminId, req.UserId, reverseProxyScheduleJSON, primaryOriginsJSON, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
reverseProxyJSON, err := json.Marshal(&serverconfigs.ReverseProxyRef{
|
||||||
|
IsPrior: false,
|
||||||
|
IsOn: true,
|
||||||
|
ReverseProxyId: reverseProxyId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Web
|
||||||
|
webId, err := models.SharedHTTPWebDAO.CreateWeb(tx, adminId, req.UserId, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable websocket
|
||||||
|
if req.EnableWebsocket {
|
||||||
|
websocketId, err := models.SharedHTTPWebsocketDAO.CreateWebsocket(tx, nil, true, nil, true, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
websocketRef, err := json.Marshal(&serverconfigs.HTTPWebsocketRef{
|
||||||
|
IsPrior: false,
|
||||||
|
IsOn: true,
|
||||||
|
WebsocketId: websocketId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = models.SharedHTTPWebDAO.UpdateWebsocket(tx, webId, websocketRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally, we create ...
|
||||||
|
serverId, err := models.SharedServerDAO.CreateServer(tx, adminId, req.UserId, serverconfigs.ServerTypeHTTPProxy, req.Domains[0], "", serverNamesJSON, isAuditing, auditingServerNamesJSON, httpJSON, httpsJSON, nil, nil, nil, nil, webId, reverseProxyJSON, req.NodeClusterId, nil, nil, nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.CreateBasicHTTPServerResponse{ServerId: serverId}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBasicTCPServer 快速创建基本的TCP网站
|
||||||
|
func (this *ServerService) CreateBasicTCPServer(ctx context.Context, req *pb.CreateBasicTCPServerRequest) (*pb.CreateBasicTCPServerResponse, error) {
|
||||||
|
adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 集群
|
||||||
|
var tx = this.NullTx()
|
||||||
|
if userId > 0 {
|
||||||
|
req.UserId = userId
|
||||||
|
|
||||||
|
nodeClusterId, err := models.SharedUserDAO.FindUserClusterId(tx, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.NodeClusterId = nodeClusterId
|
||||||
|
} else if adminId > 0 && req.UserId > 0 && req.NodeClusterId <= 0 {
|
||||||
|
// check user
|
||||||
|
existUser, err := models.SharedUserDAO.Exist(tx, req.UserId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !existUser {
|
||||||
|
return nil, errors.New("user id '" + types.String(req.UserId) + "' not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeClusterId, err := models.SharedUserDAO.FindUserClusterId(tx, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.NodeClusterId = nodeClusterId
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.NodeClusterId <= 0 {
|
||||||
|
return nil, errors.New("invalid 'nodeClusterId'")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查用户权限
|
||||||
|
if userId > 0 {
|
||||||
|
features, err := models.SharedUserDAO.FindUserFeatures(tx, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var canSpecifyTCPPort = false
|
||||||
|
for _, feature := range features {
|
||||||
|
if feature.Code == "server.tcp.port" {
|
||||||
|
canSpecifyTCPPort = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !canSpecifyTCPPort {
|
||||||
|
if len(req.TcpPorts) > 0 || len(req.TlsPorts) > 0 {
|
||||||
|
return nil, errors.New("no permission to specify tcp/tls ports")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.TcpPorts) == 0 || len(req.TlsPorts) == 0 {
|
||||||
|
// TODO 未来支持自动创建端口
|
||||||
|
return nil, errors.New("no ports valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TCP
|
||||||
|
var tcpConfig = &serverconfigs.HTTPProtocolConfig{
|
||||||
|
BaseProtocol: serverconfigs.BaseProtocol{
|
||||||
|
IsOn: true,
|
||||||
|
Listen: []*serverconfigs.NetworkAddressConfig{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, port := range req.TcpPorts {
|
||||||
|
existPort, err := models.SharedServerDAO.CheckPortIsUsing(tx, req.NodeClusterId, "tcp", int(port), 0, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if existPort {
|
||||||
|
return nil, errors.New("port '" + types.String(port) + "' already used by other server")
|
||||||
|
}
|
||||||
|
|
||||||
|
tcpConfig.BaseProtocol.Listen = append(tcpConfig.BaseProtocol.Listen, &serverconfigs.NetworkAddressConfig{
|
||||||
|
Protocol: "tcp",
|
||||||
|
PortRange: types.String(port),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
tcpJSON, err := json.Marshal(tcpConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLS
|
||||||
|
var tlsConfig = &serverconfigs.HTTPSProtocolConfig{
|
||||||
|
BaseProtocol: serverconfigs.BaseProtocol{
|
||||||
|
IsOn: true,
|
||||||
|
Listen: []*serverconfigs.NetworkAddressConfig{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, port := range req.TlsPorts {
|
||||||
|
existPort, err := models.SharedServerDAO.CheckPortIsUsing(tx, req.NodeClusterId, "tcp", int(port), 0, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if existPort {
|
||||||
|
return nil, errors.New("port '" + types.String(port) + "' already used by other server")
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConfig.BaseProtocol.Listen = append(tlsConfig.BaseProtocol.Listen, &serverconfigs.NetworkAddressConfig{
|
||||||
|
Protocol: "tls",
|
||||||
|
PortRange: types.String(port),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var certRefs = []*sslconfigs.SSLCertRef{}
|
||||||
|
for _, certId := range req.SslCertIds {
|
||||||
|
// 检查所有权
|
||||||
|
if userId > 0 {
|
||||||
|
err = models.SharedSSLCertDAO.CheckUserCert(tx, certId, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("check cert permission failed: " + err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
existCert, err := models.SharedSSLCertDAO.Exist(tx, certId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !existCert {
|
||||||
|
return nil, errors.New("cert '" + types.String(certId) + "' not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
certRefs = append(certRefs, &sslconfigs.SSLCertRef{
|
||||||
|
IsOn: true,
|
||||||
|
CertId: certId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
certRefsJSON, err := json.Marshal(certRefs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sslPolicyId, err := models.SharedSSLPolicyDAO.CreatePolicy(tx, adminId, req.UserId, false, false, "TLS 1.0", certRefsJSON, nil, false, 0, nil, false, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tlsConfig.SSLPolicyRef = &sslconfigs.SSLPolicyRef{
|
||||||
|
IsOn: true,
|
||||||
|
SSLPolicyId: sslPolicyId,
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsJSON, err := json.Marshal(tlsConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse Proxy
|
||||||
|
var reverseProxyScheduleConfig = &serverconfigs.SchedulingConfig{
|
||||||
|
Code: "random",
|
||||||
|
Options: nil,
|
||||||
|
}
|
||||||
|
reverseProxyScheduleJSON, err := json.Marshal(reverseProxyScheduleConfig)
|
||||||
|
|
||||||
|
var primaryOrigins = []*serverconfigs.OriginRef{}
|
||||||
|
for _, originAddr := range req.OriginAddrs {
|
||||||
|
u, err := url.Parse(originAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("parse origin address '" + originAddr + "' failed: " + err.Error())
|
||||||
|
}
|
||||||
|
if len(u.Scheme) == 0 || (u.Scheme != "tcp" && u.Scheme != "tls" && u.Scheme != "ssl" /** 特意不支持大写形式 **/) {
|
||||||
|
return nil, errors.New("invalid scheme in origin address '" + originAddr + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(u.Host) == 0 {
|
||||||
|
return nil, errors.New("invalid host address '" + originAddr + "', contains no host")
|
||||||
|
}
|
||||||
|
|
||||||
|
host, port, err := net.SplitHostPort(u.Host)
|
||||||
|
if err != nil || len(host) == 0 || len(port) == 0 {
|
||||||
|
err = nil // ignore error
|
||||||
|
|
||||||
|
return nil, errors.New("invalid host address '" + originAddr + "', invalid host format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if u.Scheme == "ssl" {
|
||||||
|
u.Scheme = "tls"
|
||||||
|
}
|
||||||
|
|
||||||
|
var addr = &serverconfigs.NetworkAddressConfig{
|
||||||
|
Protocol: serverconfigs.Protocol(u.Scheme),
|
||||||
|
Host: host,
|
||||||
|
PortRange: port,
|
||||||
|
}
|
||||||
|
addrJSON, err := json.Marshal(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, req.UserId, "", addrJSON, nil, "", 10, true, nil, nil, nil, 0, 0, nil, nil, "", false, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
primaryOrigins = append(primaryOrigins, &serverconfigs.OriginRef{
|
||||||
|
IsOn: true,
|
||||||
|
OriginId: originId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
primaryOriginsJSON, err := json.Marshal(primaryOrigins)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reverseProxyId, err := models.SharedReverseProxyDAO.CreateReverseProxy(tx, adminId, req.UserId, reverseProxyScheduleJSON, primaryOriginsJSON, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
reverseProxyJSON, err := json.Marshal(&serverconfigs.ReverseProxyRef{
|
||||||
|
IsPrior: false,
|
||||||
|
IsOn: true,
|
||||||
|
ReverseProxyId: reverseProxyId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally, we create ...
|
||||||
|
serverId, err := models.SharedServerDAO.CreateServer(tx, adminId, req.UserId, serverconfigs.ServerTypeTCPProxy, "TCP Service", "", nil, false, nil, nil, nil, tcpJSON, tlsJSON, nil, nil, 0, reverseProxyJSON, req.NodeClusterId, nil, nil, nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.CreateBasicTCPServerResponse{ServerId: serverId}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateServerBasic 修改服务基本信息
|
// UpdateServerBasic 修改服务基本信息
|
||||||
func (this *ServerService) UpdateServerBasic(ctx context.Context, req *pb.UpdateServerBasicRequest) (*pb.RPCSuccess, error) {
|
func (this *ServerService) UpdateServerBasic(ctx context.Context, req *pb.UpdateServerBasicRequest) (*pb.RPCSuccess, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
@@ -798,6 +1301,14 @@ func (this *ServerService) ListEnabledServersMatch(ctx context.Context, req *pb.
|
|||||||
order = "trafficOutAsc"
|
order = "trafficOutAsc"
|
||||||
} else if req.TrafficOutDesc {
|
} else if req.TrafficOutDesc {
|
||||||
order = "trafficOutDesc"
|
order = "trafficOutDesc"
|
||||||
|
} else if req.RequestsAsc {
|
||||||
|
order = "requestsAsc"
|
||||||
|
} else if req.RequestsDesc {
|
||||||
|
order = "requestsDesc"
|
||||||
|
} else if req.AttackRequestsAsc {
|
||||||
|
order = "attackRequestsAsc"
|
||||||
|
} else if req.AttackRequestsDesc {
|
||||||
|
order = "attackRequestsDesc"
|
||||||
}
|
}
|
||||||
|
|
||||||
servers, err := models.SharedServerDAO.ListEnabledServersMatch(tx, req.Offset, req.Size, req.ServerGroupId, req.Keyword, req.UserId, req.NodeClusterId, req.AuditingFlag, utils.SplitStrings(req.ProtocolFamily, ","), order)
|
servers, err := models.SharedServerDAO.ListEnabledServersMatch(tx, req.Offset, req.Size, req.ServerGroupId, req.Keyword, req.UserId, req.NodeClusterId, req.AuditingFlag, utils.SplitStrings(req.ProtocolFamily, ","), order)
|
||||||
@@ -915,11 +1426,13 @@ 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,
|
||||||
UserId: int64(server.UserId),
|
UserId: int64(server.UserId),
|
||||||
User: pbUser,
|
User: pbUser,
|
||||||
BandwidthTime: server.BandwidthTime,
|
BandwidthTime: server.BandwidthTime,
|
||||||
BandwidthBytes: int64(server.BandwidthBytes),
|
BandwidthBytes: int64(server.BandwidthBytes),
|
||||||
|
CountRequests: int64(server.CountRequests),
|
||||||
|
CountAttackRequests: int64(server.CountAttackRequests),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ func init() {
|
|||||||
for _, stat := range m {
|
for _, stat := range m {
|
||||||
// 更新服务的带宽峰值
|
// 更新服务的带宽峰值
|
||||||
if stat.ServerId > 0 {
|
if stat.ServerId > 0 {
|
||||||
err := models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests)
|
err = models.SharedServerBandwidthStatDAO.UpdateServerBandwidth(tx, stat.UserId, stat.ServerId, stat.NodeRegionId, stat.Day, stat.TimeAt, stat.Bytes, stat.TotalBytes, stat.CachedBytes, stat.AttackBytes, stat.CountRequests, stat.CountCachedRequests, stat.CountAttackRequests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
|
remotelogs.Error("ServerBandwidthStatService", "dump bandwidth stats failed: "+err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedServerDAO.UpdateServerBandwidth(tx, stat.ServerId, stat.Day+stat.TimeAt, stat.Bytes)
|
err = models.SharedServerDAO.UpdateServerBandwidth(tx, stat.ServerId, stat.Day+stat.TimeAt, stat.Bytes, stat.CountRequests, stat.CountAttackRequests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
remotelogs.Error("ServerBandwidthStatService", "update server bandwidth failed: "+err.Error())
|
remotelogs.Error("ServerBandwidthStatService", "update server bandwidth failed: "+err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -483,6 +483,7 @@ func (this *ServerGroupService) FindEnabledServerGroupConfigInfo(ctx context.Con
|
|||||||
result.HasAccessLogConfig = webConfig != nil && webConfig.AccessLogRef != nil && webConfig.AccessLogRef.IsPrior
|
result.HasAccessLogConfig = webConfig != nil && webConfig.AccessLogRef != nil && webConfig.AccessLogRef.IsPrior
|
||||||
result.HasStatConfig = webConfig != nil && webConfig.StatRef != nil && webConfig.StatRef.IsPrior
|
result.HasStatConfig = webConfig != nil && webConfig.StatRef != nil && webConfig.StatRef.IsPrior
|
||||||
result.HasCompressionConfig = webConfig != nil && webConfig.Compression != nil && webConfig.Compression.IsPrior
|
result.HasCompressionConfig = webConfig != nil && webConfig.Compression != nil && webConfig.Compression.IsPrior
|
||||||
|
result.HasOptimizationConfig = webConfig != nil && webConfig.Optimization != nil && webConfig.Optimization.IsPrior
|
||||||
result.HasWebsocketConfig = webConfig != nil && webConfig.WebsocketRef != nil && webConfig.WebsocketRef.IsPrior
|
result.HasWebsocketConfig = webConfig != nil && webConfig.WebsocketRef != nil && webConfig.WebsocketRef.IsPrior
|
||||||
result.HasRequestHeadersConfig = webConfig != nil && webConfig.RequestHeaderPolicyRef != nil && webConfig.RequestHeaderPolicyRef.IsPrior
|
result.HasRequestHeadersConfig = webConfig != nil && webConfig.RequestHeaderPolicyRef != nil && webConfig.RequestHeaderPolicyRef.IsPrior
|
||||||
result.HasResponseHeadersConfig = webConfig != nil && webConfig.ResponseHeaderPolicyRef != nil && webConfig.ResponseHeaderPolicyRef.IsPrior
|
result.HasResponseHeadersConfig = webConfig != nil && webConfig.ResponseHeaderPolicyRef != nil && webConfig.ResponseHeaderPolicyRef.IsPrior
|
||||||
|
|||||||
@@ -62,15 +62,15 @@ func (this *ServerRegionCityMonthlyStatService) FindTopServerRegionCityMonthlySt
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionProvince = &pb.RegionProvince{
|
pbStat.RegionProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.DisplayName(),
|
Name: province.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionCity = &pb.RegionCity{
|
pbStat.RegionCity = &pb.RegionCity{
|
||||||
Id: int64(city.Id),
|
Id: int64(city.ValueId),
|
||||||
Name: city.DisplayName(),
|
Name: city.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func (this *ServerRegionCountryMonthlyStatService) FindTopServerRegionCountryMon
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ func (this *ServerRegionProviderMonthlyStatService) FindTopServerRegionProviderM
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pbStat.RegionProvider = &pb.RegionProvider{
|
pbStat.RegionProvider = &pb.RegionProvider{
|
||||||
Id: int64(provider.Id),
|
Id: int64(provider.ValueId),
|
||||||
Name: provider.DisplayName(),
|
Name: provider.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ func (this *ServerRegionProvinceMonthlyStatService) FindTopServerRegionProvinceM
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pbStat.RegionCountry = &pb.RegionCountry{
|
pbStat.RegionCountry = &pb.RegionCountry{
|
||||||
Id: int64(country.Id),
|
Id: int64(country.ValueId),
|
||||||
Name: country.DisplayName(),
|
Name: country.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStat.RegionProvince = &pb.RegionProvince{
|
pbStat.RegionProvince = &pb.RegionProvince{
|
||||||
Id: int64(province.Id),
|
Id: int64(province.ValueId),
|
||||||
Name: province.DisplayName(),
|
Name: province.DisplayName(),
|
||||||
}
|
}
|
||||||
pbStats = append(pbStats, pbStat)
|
pbStats = append(pbStats, pbStat)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func (this *SSLPolicyService) CreateSSLPolicy(ctx context.Context, req *pb.Creat
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
policyId, err := models.SharedSSLPolicyDAO.CreatePolicy(tx, adminId, userId, req.Http2Enabled, req.MinVersion, req.SslCertsJSON, req.HstsJSON, req.OcspIsOn, req.ClientAuthType, req.ClientCACertsJSON, req.CipherSuitesIsOn, req.CipherSuites)
|
policyId, err := models.SharedSSLPolicyDAO.CreatePolicy(tx, adminId, userId, req.Http2Enabled, req.Http3Enabled, req.MinVersion, req.SslCertsJSON, req.HstsJSON, req.OcspIsOn, req.ClientAuthType, req.ClientCACertsJSON, req.CipherSuitesIsOn, req.CipherSuites)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -63,13 +63,13 @@ func (this *SSLPolicyService) UpdateSSLPolicy(ctx context.Context, req *pb.Updat
|
|||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
if userId > 0 {
|
if userId > 0 {
|
||||||
err := models.SharedSSLPolicyDAO.CheckUserPolicy(tx, userId, req.SslPolicyId)
|
err = models.SharedSSLPolicyDAO.CheckUserPolicy(tx, userId, req.SslPolicyId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("check ssl policy failed: " + err.Error())
|
return nil, errors.New("check ssl policy failed: " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedSSLPolicyDAO.UpdatePolicy(tx, req.SslPolicyId, req.Http2Enabled, req.MinVersion, req.SslCertsJSON, req.HstsJSON, req.OcspIsOn, req.ClientAuthType, req.ClientCACertsJSON, req.CipherSuitesIsOn, req.CipherSuites)
|
err = models.SharedSSLPolicyDAO.UpdatePolicy(tx, req.SslPolicyId, req.Http2Enabled, req.Http3Enabled, req.MinVersion, req.SslCertsJSON, req.HstsJSON, req.OcspIsOn, req.ClientAuthType, req.ClientCACertsJSON, req.CipherSuitesIsOn, req.CipherSuites)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ func (this *UserService) FindEnabledUser(ctx context.Context, req *pb.FindEnable
|
|||||||
IsEnterpriseIdentified: isEnterpriseIdentified,
|
IsEnterpriseIdentified: isEnterpriseIdentified,
|
||||||
BandwidthAlgo: user.BandwidthAlgo,
|
BandwidthAlgo: user.BandwidthAlgo,
|
||||||
OtpLogin: pbOtpAuth,
|
OtpLogin: pbOtpAuth,
|
||||||
|
Lang: user.Lang,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,13 @@ func (this *Setup) Run() error {
|
|||||||
}
|
}
|
||||||
for _, db := range config.DBs {
|
for _, db := range config.DBs {
|
||||||
// 可以同时运行多条语句
|
// 可以同时运行多条语句
|
||||||
db.Dsn += "&multiStatements=true"
|
if !strings.Contains(db.Dsn, "multiStatements=") {
|
||||||
|
if strings.Contains(db.Dsn, "?") {
|
||||||
|
db.Dsn += "&multiStatements=true"
|
||||||
|
} else {
|
||||||
|
db.Dsn += "?multiStatements=true"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dbConfig, ok := config.DBs[Tea.Env]
|
dbConfig, ok := config.DBs[Tea.Env]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
49857
internal/setup/sql.json
49857
internal/setup/sql.json
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user