Compare commits

..

44 Commits

Author SHA1 Message Date
刘祥超
50055c1045 提交SQL 2021-06-21 11:25:13 +08:00
刘祥超
cca97f5c51 管理员也支持AccessKey,Rest API增加所有的服务 2021-06-20 19:22:24 +08:00
刘祥超
1bfaf041ea 修复用户无法修改关联集群的Bug 2021-06-19 22:19:12 +08:00
刘祥超
927b5b6fd3 阶段性提交 2021-06-17 21:17:53 +08:00
刘祥超
1afaa0bc8d 调整版本为0.2.3 2021-06-17 18:45:55 +08:00
刘祥超
7312a7aa94 调整版本为0.2.2 2021-06-17 18:07:49 +08:00
刘祥超
fd18739b0a REST API输出时增加application/json; charset=utf-8 Header 2021-06-16 10:48:31 +08:00
刘祥超
d92f56e7fe 用户AccessKey:增加最近访问时间、修复AccessKey没有区分用户的Bug 2021-06-16 10:48:08 +08:00
刘祥超
a1a7ec8c93 调整边缘节点版本 2021-06-16 09:37:54 +08:00
刘祥超
951fdf0927 调整版本为0.2.1 2021-06-16 08:31:02 +08:00
刘祥超
7d3328f75b 节点日志计数从1开始(以前是0) 2021-06-14 20:39:39 +08:00
刘祥超
8db39a6b36 更新各个节点版本 2021-06-14 20:39:10 +08:00
刘祥超
71681b1c5d 提供下载最新边缘节点API 2021-06-10 19:21:45 +08:00
刘祥超
6b2a015015 创建缓存策略时默认加入缓存条件 2021-06-10 10:50:56 +08:00
刘祥超
9e74baf37b 路径规则、重写规则、URL跳转规则均支持匹配条件 2021-06-09 21:44:38 +08:00
刘祥超
b651d94bf5 请求统计增加即时、按天 2021-06-08 15:10:08 +08:00
刘祥超
b61433c5f8 更新SQL 2021-06-08 11:23:35 +08:00
刘祥超
c4d2191110 增加服务流量统计 2021-06-08 11:18:27 +08:00
刘祥超
f6159c646c 修改反向代理回源主机名默认值 2021-06-07 17:23:10 +08:00
刘祥超
9cc7d54b64 健康检查支持IPv6 2021-06-07 10:06:16 +08:00
刘祥超
05ce1d327b 边缘节点IP支持IPV6 2021-06-07 10:02:07 +08:00
刘祥超
111df18204 WAF策略支持搜索 2021-06-07 08:58:26 +08:00
刘祥超
bbcdf167b1 缓存策略列表支持搜索 2021-06-07 08:44:19 +08:00
刘祥超
d62a44b1ac 聚合服务相关日志 2021-06-06 13:40:33 +08:00
刘祥超
969bb2bcda 日志级别增加success 2021-06-06 13:40:25 +08:00
刘祥超
6dcd3f2a98 域名服务集群创建时可以选择开启访问日志 2021-06-05 15:39:02 +08:00
刘祥超
7936dc85a9 API认证超时时增加检查系统时钟提示 2021-06-04 15:34:58 +08:00
刘祥超
94c4098de5 兼容部分API老命名 2021-06-04 11:41:50 +08:00
刘祥超
5b0aef8d4a 修复用户创建服务时提示resource not found的问题 2021-06-04 11:23:01 +08:00
刘祥超
4571b95e4a 服务访问日志增加关键词搜索 2021-06-04 10:15:41 +08:00
刘祥超
b9cba4c7df DNS访问日志可以使用关键词搜索 2021-06-04 09:09:14 +08:00
刘祥超
b46b5dc05f 修复域名服务集群检测新版本节点的Bug 2021-06-03 22:08:38 +08:00
刘祥超
ef5630ba4a 实现在域名解析中使用EdgeDNS 2021-06-02 18:13:48 +08:00
刘祥超
fe6c610d56 更新SQL 2021-06-02 11:54:05 +08:00
刘祥超
442dd195ca 域名服务增加访问日志 2021-06-02 11:53:24 +08:00
刘祥超
e9e4abff03 实现域名、记录同步等API 2021-06-01 16:43:00 +08:00
刘祥超
2a3fbd080e [域名服务]实现基本的线路配置 2021-05-30 16:31:43 +08:00
刘祥超
9d7f1a2702 更新SQL 2021-05-27 17:29:31 +08:00
刘祥超
57dcbce775 实现基本的域名、记录管理 2021-05-27 17:09:07 +08:00
刘祥超
a71bf9ed79 实现最基本的域名服务节点管理 2021-05-26 14:40:05 +08:00
刘祥超
725692ce94 优化API命名 2021-05-25 17:48:55 +08:00
刘祥超
ea15096dc3 优化API命名 2021-05-25 17:08:58 +08:00
刘祥超
a07dbb718f 实现域名服务器集群管理 2021-05-25 15:49:13 +08:00
刘祥超
18381b76fb 变更版本为0.2.0 2021-05-25 15:49:04 +08:00
135 changed files with 6233 additions and 854 deletions

13
go.mod
View File

@@ -13,15 +13,18 @@ require (
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/go-sql-driver/mysql v1.5.0
github.com/go-yaml/yaml v2.1.0+incompatible
github.com/golang/protobuf v1.4.2
github.com/golang/protobuf v1.5.2
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f
github.com/lionsoul2014/ip2region v2.2.0-release+incompatible
github.com/mozillazg/go-pinyin v0.18.0
github.com/pkg/sftp v1.12.0
github.com/shirou/gopsutil v2.20.9+incompatible
github.com/shirou/gopsutil v3.21.5+incompatible
github.com/tklauser/go-sysconf v0.3.6 // indirect
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299
google.golang.org/grpc v1.32.0
google.golang.org/protobuf v1.25.0
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced // indirect
google.golang.org/grpc v1.38.0
google.golang.org/protobuf v1.26.0
gopkg.in/yaml.v2 v2.4.0 // indirect
)

47
go.sum
View File

@@ -68,6 +68,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.13.2/go.mod h1:27kfc1apuifUmJhp069y0+hwlKDg4bd8LWlu7oKeZvM=
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/cpu/goacmedns v0.0.3/go.mod h1:4MipLkI+qScwqtVxcNO6okBhbgRrr7/tKXUSgSL0teQ=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -83,6 +84,7 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP
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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/exoscale/egoscale v0.23.0/go.mod h1:hRo78jkjkCDKpivQdRBEpNYF5+cVpCJCPDg2/r45KaY=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
@@ -134,6 +136,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -143,6 +148,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@@ -153,6 +159,7 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gophercloud/gophercloud v0.6.1-0.20191122030953-d8ac278c1c9d/go.mod h1:ozGNgr9KYOVATV5jsgHl/ceCDXGuguqOZAzoQ/2vcNM=
@@ -175,12 +182,6 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
github.com/iwind/TeaGo v0.0.0-20200923021120-f5d76441fe9e/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
github.com/iwind/TeaGo v0.0.0-20210125103732-4d79fc3c3d0b h1:niQL2t//041GUaqDPM5D+ldyr0Ng2WKwZJHPRLQhQtk=
github.com/iwind/TeaGo v0.0.0-20210125103732-4d79fc3c3d0b/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
github.com/iwind/TeaGo v0.0.0-20210302120856-7588e79bdbe3 h1:k9K3HHMmkF7HYyIHz21AtmYH4Zdk/8OI98a8P0O8o1I=
github.com/iwind/TeaGo v0.0.0-20210302120856-7588e79bdbe3/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
github.com/iwind/TeaGo v0.0.0-20210325033016-3279bdaa087d h1:FQTYJmZeCMdwM0Bz+C4h31SDBt04ap6A4JOjm+FfYwk=
github.com/iwind/TeaGo v0.0.0-20210325033016-3279bdaa087d/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f h1:r2O8PONj/KiuZjJHVHn7KlCePUIjNtgAmvLfgRafQ8o=
github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
@@ -289,6 +290,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/sacloud/libsacloud v1.36.2/go.mod h1:P7YAOVmnIn3DKHqCZcUKYUXmSwGBm3yS7IBEjKVSrjg=
github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ=
github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.21.5+incompatible h1:OloQyEerMi7JUrXiNzy8wQ5XN+baemxSl12QgIzt0jc=
github.com/shirou/gopsutil v3.21.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -306,6 +309,10 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4=
github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI=
github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA=
github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM=
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
@@ -313,6 +320,7 @@ github.com/vultr/govultr v0.5.0/go.mod h1:wZZXZbYbqyY1n3AldoeYNZK4Wnmmoq6dNFkvd5
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -356,6 +364,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -363,6 +372,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -391,6 +401,9 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -403,6 +416,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -439,11 +453,23 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -482,10 +508,12 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
@@ -523,6 +551,8 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced h1:c5geK1iMU3cDKtFrCVQIcjR3W+JOZMuhIyICMCTbtus=
google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -536,6 +566,8 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -546,6 +578,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -2,6 +2,7 @@ package acme
import (
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/go-acme/lego/v4/challenge/dns01"
"strings"
@@ -24,15 +25,15 @@ func (this *DNSProvider) Present(domain, token, keyAuth string) error {
return errors.New("invalid fqdn value")
}
recordName := fqdn[:index]
record, err := this.raw.QueryRecord(domain, recordName, dnsclients.RecordTypeTXT)
record, err := this.raw.QueryRecord(domain, recordName, dnstypes.RecordTypeTXT)
if err != nil {
return errors.New("query DNS record failed: " + err.Error())
}
if record == nil {
err = this.raw.AddRecord(domain, &dnsclients.Record{
err = this.raw.AddRecord(domain, &dnstypes.Record{
Id: "",
Name: recordName,
Type: dnsclients.RecordTypeTXT,
Type: dnstypes.RecordTypeTXT,
Value: value,
Route: this.raw.DefaultRoute(),
})
@@ -40,9 +41,9 @@ func (this *DNSProvider) Present(domain, token, keyAuth string) error {
return errors.New("create DNS record failed: " + err.Error())
}
} else {
err = this.raw.UpdateRecord(domain, record, &dnsclients.Record{
err = this.raw.UpdateRecord(domain, record, &dnstypes.Record{
Name: recordName,
Type: dnsclients.RecordTypeTXT,
Type: dnstypes.RecordTypeTXT,
Value: value,
Route: this.raw.DefaultRoute(),
})

View File

@@ -1,7 +1,7 @@
package teaconst
const (
Version = "0.1.1"
Version = "0.2.3"
ProductName = "Edge API"
ProcessName = "edge-api"
@@ -18,9 +18,9 @@ const (
// 其他节点版本号,用来检测是否有需要升级的节点
NodeVersion = "0.1.1"
UserNodeVersion = "0.0.7"
AuthorityNodeVersion = "0.0.1"
MonitorNodeVersion = "0.0.1"
NodeVersion = "0.2.3"
UserNodeVersion = "0.0.8"
AuthorityNodeVersion = "0.0.2"
MonitorNodeVersion = "0.0.2"
DNSNodeVersion = "0.0.1"
)

7
internal/const/vars.go Normal file
View File

@@ -0,0 +1,7 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package teaconst
var (
IsPlus = false
)

View File

@@ -1,6 +1,7 @@
package models
import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -29,10 +30,23 @@ func init() {
})
}
// 生成AccessToken
func (this *APIAccessTokenDAO) GenerateAccessToken(tx *dbs.Tx, userId int64) (token string, expiresAt int64, err error) {
// GenerateAccessToken 生成AccessToken
func (this *APIAccessTokenDAO) GenerateAccessToken(tx *dbs.Tx, adminId int64, userId int64) (token string, expiresAt int64, err error) {
if adminId <= 0 && userId <= 0 {
err = errors.New("either 'adminId' or 'userId' should not be zero")
return
}
if adminId > 0 {
userId = 0
}
if userId > 0 {
adminId = 0
}
// 查询以前的
accessToken, err := this.Query(tx).
Attr("adminId", adminId).
Attr("userId", userId).
Find()
if err != nil {
@@ -48,6 +62,7 @@ func (this *APIAccessTokenDAO) GenerateAccessToken(tx *dbs.Tx, userId int64) (to
op.Id = accessToken.(*APIAccessToken).Id
}
op.AdminId = adminId
op.UserId = userId
op.Token = token
op.CreatedAt = time.Now().Unix()
@@ -56,7 +71,7 @@ func (this *APIAccessTokenDAO) GenerateAccessToken(tx *dbs.Tx, userId int64) (to
return
}
// 查找AccessToken
// FindAccessToken 查找AccessToken
func (this *APIAccessTokenDAO) FindAccessToken(tx *dbs.Tx, token string) (*APIAccessToken, error) {
one, err := this.Query(tx).
Attr("token", token).

View File

@@ -1,9 +1,10 @@
package models
// API访问令牌
// APIAccessToken API访问令牌
type APIAccessToken struct {
Id uint64 `field:"id"` // ID
UserId uint32 `field:"userId"` // 用户ID
AdminId uint32 `field:"adminId"` // 管理员ID
Token string `field:"token"` // 令牌
CreatedAt uint64 `field:"createdAt"` // 创建时间
ExpiredAt uint64 `field:"expiredAt"` // 过期时间
@@ -12,6 +13,7 @@ type APIAccessToken struct {
type APIAccessTokenOperator struct {
Id interface{} // ID
UserId interface{} // 用户ID
AdminId interface{} // 管理员ID
Token interface{} // 令牌
CreatedAt interface{} // 创建时间
ExpiredAt interface{} // 过期时间

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -97,7 +98,7 @@ func (this *APINodeDAO) CreateAPINode(tx *dbs.Tx, name string, description strin
return 0, err
}
secret := rands.String(32)
err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, NodeRoleAPI)
err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleAPI)
if err != nil {
return
}

View File

@@ -1,6 +1,7 @@
package models
import (
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -34,7 +35,7 @@ func init() {
})
}
// 启用条目
// EnableApiToken 启用条目
func (this *ApiTokenDAO) EnableApiToken(tx *dbs.Tx, id uint32) (rowsAffected int64, err error) {
return this.Query(tx).
Pk(id).
@@ -42,7 +43,7 @@ func (this *ApiTokenDAO) EnableApiToken(tx *dbs.Tx, id uint32) (rowsAffected int
Update()
}
// 禁用条目
// DisableApiToken 禁用条目
func (this *ApiTokenDAO) DisableApiToken(tx *dbs.Tx, id uint32) (rowsAffected int64, err error) {
return this.Query(tx).
Pk(id).
@@ -50,7 +51,7 @@ func (this *ApiTokenDAO) DisableApiToken(tx *dbs.Tx, id uint32) (rowsAffected in
Update()
}
// 查找启用中的条目
// FindEnabledApiToken 查找启用中的条目
func (this *ApiTokenDAO) FindEnabledApiToken(tx *dbs.Tx, id uint32) (*ApiToken, error) {
result, err := this.Query(tx).
Pk(id).
@@ -62,7 +63,7 @@ func (this *ApiTokenDAO) FindEnabledApiToken(tx *dbs.Tx, id uint32) (*ApiToken,
return result.(*ApiToken), err
}
// 获取可缓存的节点Token信息
// FindEnabledTokenWithNodeCacheable 获取可缓存的节点Token信息
func (this *ApiTokenDAO) FindEnabledTokenWithNodeCacheable(tx *dbs.Tx, nodeId string) (*ApiToken, error) {
SharedCacheLocker.RLock()
token, ok := apiTokenCacheMap[nodeId]
@@ -85,7 +86,7 @@ func (this *ApiTokenDAO) FindEnabledTokenWithNodeCacheable(tx *dbs.Tx, nodeId st
return nil, err
}
// 获取节点Token信息并可以缓存
// FindEnabledTokenWithNode 获取节点Token信息并可以缓存
func (this *ApiTokenDAO) FindEnabledTokenWithNode(tx *dbs.Tx, nodeId string) (*ApiToken, error) {
one, err := this.Query(tx).
Attr("nodeId", nodeId).
@@ -97,7 +98,7 @@ func (this *ApiTokenDAO) FindEnabledTokenWithNode(tx *dbs.Tx, nodeId string) (*A
return nil, err
}
// 根据角色获取节点
// FindEnabledTokenWithRole 根据角色获取节点
func (this *ApiTokenDAO) FindEnabledTokenWithRole(tx *dbs.Tx, role string) (*ApiToken, error) {
one, err := this.Query(tx).
Attr("role", role).
@@ -109,8 +110,8 @@ func (this *ApiTokenDAO) FindEnabledTokenWithRole(tx *dbs.Tx, role string) (*Api
return nil, err
}
// 保存API Token
func (this *ApiTokenDAO) CreateAPIToken(tx *dbs.Tx, nodeId string, secret string, role NodeRole) error {
// CreateAPIToken 保存API Token
func (this *ApiTokenDAO) CreateAPIToken(tx *dbs.Tx, nodeId string, secret string, role nodeconfigs.NodeRole) error {
op := NewApiTokenOperator()
op.NodeId = nodeId
op.Secret = secret

View File

@@ -2,9 +2,11 @@ package authority
import (
"encoding/json"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
timeutil "github.com/iwind/TeaGo/utils/time"
"time"
)
@@ -26,6 +28,9 @@ var SharedAuthorityKeyDAO *AuthorityKeyDAO
func init() {
dbs.OnReady(func() {
SharedAuthorityKeyDAO = NewAuthorityKeyDAO()
// 初始化IsPlus值
_, _ = SharedAuthorityKeyDAO.IsPlus(nil)
})
}
@@ -72,7 +77,14 @@ func (this *AuthorityKeyDAO) ReadKey(tx *dbs.Tx) (key *AuthorityKey, err error)
if one == nil {
return nil, nil
}
return one.(*AuthorityKey), nil
key = one.(*AuthorityKey)
// 顺便更新相关变量
if key.DayTo >= timeutil.Format("Y-m-d") {
teaconst.IsPlus = true
}
return
}
// ResetKey 重置Key
@@ -81,3 +93,16 @@ func (this *AuthorityKeyDAO) ResetKey(tx *dbs.Tx) error {
Delete()
return err
}
// IsPlus 判断是否为企业版
func (this *AuthorityKeyDAO) IsPlus(tx *dbs.Tx) (bool, error) {
key, err := this.ReadKey(tx)
if err != nil {
return false, err
}
if key == nil {
return false, nil
}
teaconst.IsPlus = key.DayTo >= timeutil.Format("Y-m-d")
return teaconst.IsPlus, nil
}

View File

@@ -7,17 +7,17 @@ import (
)
func TestAuthorityKeyDAO_UpdateValue(t *testing.T) {
err := NewAuthorityKeyDAO().UpdateValue(nil, "12345678")
err := NewAuthorityKeyDAO().UpdateKey(nil, "12345678", "", "", "", []string{}, "")
if err != nil {
t.Fatal(err)
}
t.Logf("ok")
t.Log("ok")
}
func TestAuthorityKeyDAO_ReadValue(t *testing.T) {
value, err := NewAuthorityKeyDAO().ReadValue(nil)
value, err := NewAuthorityKeyDAO().ReadKey(nil)
if err != nil {
t.Fatal(err)
}
t.Logf(value)
t.Log(value)
}

View File

@@ -4,6 +4,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -113,7 +114,7 @@ func (this *AuthorityNodeDAO) CreateAuthorityNode(tx *dbs.Tx, name string, descr
return 0, err
}
secret := rands.String(32)
err = models.NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, models.NodeRoleAuthority)
err = models.NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleAuthority)
if err != nil {
return
}

View File

@@ -3,6 +3,7 @@ package models
import (
"fmt"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/logs"
@@ -15,16 +16,29 @@ import (
"time"
)
var accessLogDBMapping = map[int64]*dbs.DB{} // dbNodeId => DB
var accessLogDAOMapping = map[int64]*HTTPAccessLogDAOWrapper{} // dbNodeId => DAO
var accessLogDBMapping = map[int64]*dbs.DB{} // dbNodeId => DB
var accessLogLocker = &sync.RWMutex{}
var accessLogTableMapping = map[string]bool{} // tableName_crc(dsn) => true
// HTTP服务访问
var httpAccessLogDAOMapping = map[int64]*HTTPAccessLogDAOWrapper{} // dbNodeId => DAO
var httpAccessLogTableMapping = map[string]bool{} // tableName_crc(dsn) => true
// DNS服务访问
var nsAccessLogDAOMapping = map[int64]*NSAccessLogDAOWrapper{} // dbNodeId => DAO
var nsAccessLogTableMapping = map[string]bool{} // tableName_crc(dsn) => true
// HTTPAccessLogDAOWrapper HTTP访问日志DAO
type HTTPAccessLogDAOWrapper struct {
DAO *HTTPAccessLogDAO
NodeId int64
}
// NSAccessLogDAOWrapper NS访问日志DAO
type NSAccessLogDAOWrapper struct {
DAO *NSAccessLogDAO
NodeId int64
}
func init() {
initializer := NewDBNodeInitializer()
dbs.OnReadyDone(func() {
@@ -33,12 +47,26 @@ func init() {
}
// 获取获取DAO
func randomAccessLogDAO() (dao *HTTPAccessLogDAOWrapper) {
func randomHTTPAccessLogDAO() (dao *HTTPAccessLogDAOWrapper) {
accessLogLocker.RLock()
if len(accessLogDAOMapping) == 0 {
if len(httpAccessLogDAOMapping) == 0 {
dao = nil
} else {
for _, d := range accessLogDAOMapping {
for _, d := range httpAccessLogDAOMapping {
dao = d
break
}
}
accessLogLocker.RUnlock()
return
}
func randomNSAccessLogDAO() (dao *NSAccessLogDAOWrapper) {
accessLogLocker.RLock()
if len(nsAccessLogDAOMapping) == 0 {
dao = nil
} else {
for _, d := range nsAccessLogDAOMapping {
dao = d
break
}
@@ -48,7 +76,7 @@ func randomAccessLogDAO() (dao *HTTPAccessLogDAOWrapper) {
}
// 检查表格是否存在
func findAccessLogTableName(db *dbs.DB, day string) (tableName string, ok bool, err error) {
func findHTTPAccessLogTableName(db *dbs.DB, day string) (tableName string, ok bool, err error) {
if !regexp.MustCompile(`^\d{8}$`).MatchString(day) {
err = errors.New("invalid day '" + day + "', should be YYYYMMDD")
return
@@ -63,7 +91,36 @@ func findAccessLogTableName(db *dbs.DB, day string) (tableName string, ok bool,
cacheKey := tableName + "_" + fmt.Sprintf("%d", crc32.ChecksumIEEE([]byte(config.Dsn)))
accessLogLocker.RLock()
_, ok = accessLogTableMapping[cacheKey]
_, ok = httpAccessLogTableMapping[cacheKey]
accessLogLocker.RUnlock()
if ok {
return tableName, true, nil
}
tableNames, err := db.TableNames()
if err != nil {
return tableName, false, err
}
return tableName, lists.ContainsString(tableNames, tableName), nil
}
func findNSAccessLogTableName(db *dbs.DB, day string) (tableName string, ok bool, err error) {
if !regexp.MustCompile(`^\d{8}$`).MatchString(day) {
err = errors.New("invalid day '" + day + "', should be YYYYMMDD")
return
}
config, err := db.Config()
if err != nil {
return "", false, err
}
tableName = "edgeNSAccessLogs_" + day
cacheKey := tableName + "_" + fmt.Sprintf("%d", crc32.ChecksumIEEE([]byte(config.Dsn)))
accessLogLocker.RLock()
_, ok = nsAccessLogTableMapping[cacheKey]
accessLogLocker.RUnlock()
if ok {
return tableName, true, nil
@@ -78,7 +135,7 @@ func findAccessLogTableName(db *dbs.DB, day string) (tableName string, ok bool,
}
// 根据日期获取表名
func findAccessLogTable(db *dbs.DB, day string, force bool) (string, error) {
func findHTTPAccessLogTable(db *dbs.DB, day string, force bool) (string, error) {
config, err := db.Config()
if err != nil {
return "", err
@@ -89,7 +146,7 @@ func findAccessLogTable(db *dbs.DB, day string, force bool) (string, error) {
if !force {
accessLogLocker.RLock()
_, ok := accessLogTableMapping[cacheKey]
_, ok := httpAccessLogTableMapping[cacheKey]
accessLogLocker.RUnlock()
if ok {
return tableName, nil
@@ -103,7 +160,7 @@ func findAccessLogTable(db *dbs.DB, day string, force bool) (string, error) {
if lists.ContainsString(tableNames, tableName) {
accessLogLocker.Lock()
accessLogTableMapping[cacheKey] = true
httpAccessLogTableMapping[cacheKey] = true
accessLogLocker.Unlock()
return tableName, nil
}
@@ -115,13 +172,56 @@ func findAccessLogTable(db *dbs.DB, day string, force bool) (string, error) {
}
accessLogLocker.Lock()
accessLogTableMapping[cacheKey] = true
httpAccessLogTableMapping[cacheKey] = true
accessLogLocker.Unlock()
return tableName, nil
}
// 初始化数据库连接
func findNSAccessLogTable(db *dbs.DB, day string, force bool) (string, error) {
config, err := db.Config()
if err != nil {
return "", err
}
tableName := "edgeNSAccessLogs_" + day
cacheKey := tableName + "_" + fmt.Sprintf("%d", crc32.ChecksumIEEE([]byte(config.Dsn)))
if !force {
accessLogLocker.RLock()
_, ok := nsAccessLogTableMapping[cacheKey]
accessLogLocker.RUnlock()
if ok {
return tableName, nil
}
}
tableNames, err := db.TableNames()
if err != nil {
return tableName, err
}
if lists.ContainsString(tableNames, tableName) {
accessLogLocker.Lock()
nsAccessLogTableMapping[cacheKey] = true
accessLogLocker.Unlock()
return tableName, nil
}
// 创建表格
_, err = db.Exec("CREATE TABLE `" + tableName + "` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `nodeId` int(11) unsigned DEFAULT '0' COMMENT '节点ID',\n `domainId` int(11) unsigned DEFAULT '0' COMMENT '域名ID',\n `recordId` int(11) unsigned DEFAULT '0' COMMENT '记录ID',\n `content` json DEFAULT NULL COMMENT '访问数据',\n `requestId` varchar(128) DEFAULT NULL COMMENT '请求ID',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n PRIMARY KEY (`id`),\n KEY `nodeId` (`nodeId`),\n KEY `domainId` (`domainId`),\n KEY `recordId` (`recordId`),\n KEY `requestId` (`requestId`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='域名服务访问日志';")
if err != nil {
return tableName, err
}
accessLogLocker.Lock()
nsAccessLogTableMapping[cacheKey] = true
accessLogLocker.Unlock()
return tableName, nil
}
// DBNodeInitializer 初始化数据库连接
type DBNodeInitializer struct {
}
@@ -129,7 +229,7 @@ func NewDBNodeInitializer() *DBNodeInitializer {
return &DBNodeInitializer{}
}
// 启动
// Start 启动
func (this *DBNodeInitializer) Start() {
// 初始运行
err := this.loop()
@@ -166,7 +266,8 @@ func (this *DBNodeInitializer) loop() error {
if !lists.ContainsInt64(nodeIds, nodeId) {
closingDbs = append(closingDbs, db)
delete(accessLogDBMapping, nodeId)
delete(accessLogDAOMapping, nodeId)
delete(httpAccessLogDAOMapping, nodeId)
delete(nsAccessLogDAOMapping, nodeId)
logs.Println("[DB_NODE]close db node '" + strconv.FormatInt(nodeId, 10) + "'")
}
}
@@ -212,46 +313,94 @@ func (this *DBNodeInitializer) loop() error {
}
// 检查表是否存在
tableName, err := findAccessLogTable(db, timeutil.Format("Ymd"), false)
if err != nil {
if !strings.Contains(err.Error(), "1050") { // 非表格已存在错误
logs.Println("[DB_NODE]create first table in database node failed: " + err.Error())
// httpAccessLog
{
tableName, err := findHTTPAccessLogTable(db, timeutil.Format("Ymd"), false)
if err != nil {
if !strings.Contains(err.Error(), "1050") { // 非表格已存在错误
logs.Println("[DB_NODE]create first table in database node failed: " + err.Error())
// 创建节点日志
createLogErr := SharedNodeLogDAO.CreateLog(nil, NodeRoleDatabase, nodeId, 0, "error", "ACCESS_LOG", "can not create access log table: "+err.Error(), time.Now().Unix())
if createLogErr != nil {
logs.Println("[NODE_LOG]" + createLogErr.Error())
// 创建节点日志
createLogErr := SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleDatabase, nodeId, 0, "error", "ACCESS_LOG", "can not create access log table: "+err.Error(), time.Now().Unix())
if createLogErr != nil {
logs.Println("[NODE_LOG]" + createLogErr.Error())
}
continue
} else {
err = nil
}
continue
} else {
err = nil
}
daoObject := dbs.DAOObject{
Instance: db,
DB: node.Name + "(id:" + strconv.Itoa(int(node.Id)) + ")",
Table: tableName,
PkName: "id",
Model: new(HTTPAccessLog),
}
err = daoObject.Init()
if err != nil {
logs.Println("[DB_NODE]initialize dao failed: " + err.Error())
continue
}
accessLogLocker.Lock()
accessLogDBMapping[nodeId] = db
dao := &HTTPAccessLogDAO{
DAOObject: daoObject,
}
httpAccessLogDAOMapping[nodeId] = &HTTPAccessLogDAOWrapper{
DAO: dao,
NodeId: nodeId,
}
accessLogLocker.Unlock()
}
daoObject := dbs.DAOObject{
Instance: db,
DB: node.Name + "(id:" + strconv.Itoa(int(node.Id)) + ")",
Table: tableName,
PkName: "id",
Model: new(HTTPAccessLog),
}
err = daoObject.Init()
if err != nil {
logs.Println("[DB_NODE]initialize dao failed: " + err.Error())
continue
}
accessLogLocker.Lock()
accessLogDBMapping[nodeId] = db
dao := &HTTPAccessLogDAO{
DAOObject: daoObject,
// nsAccessLog
{
tableName, err := findNSAccessLogTable(db, timeutil.Format("Ymd"), false)
if err != nil {
if !strings.Contains(err.Error(), "1050") { // 非表格已存在错误
logs.Println("[DB_NODE]create first table in database node failed: " + err.Error())
// 创建节点日志
createLogErr := SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleDatabase, nodeId, 0, "error", "ACCESS_LOG", "can not create access log table: "+err.Error(), time.Now().Unix())
if createLogErr != nil {
logs.Println("[NODE_LOG]" + createLogErr.Error())
}
continue
} else {
err = nil
}
}
daoObject := dbs.DAOObject{
Instance: db,
DB: node.Name + "(id:" + strconv.Itoa(int(node.Id)) + ")",
Table: tableName,
PkName: "id",
Model: new(NSAccessLog),
}
err = daoObject.Init()
if err != nil {
logs.Println("[DB_NODE]initialize dao failed: " + err.Error())
continue
}
accessLogLocker.Lock()
accessLogDBMapping[nodeId] = db
dao := &NSAccessLogDAO{
DAOObject: daoObject,
}
nsAccessLogDAOMapping[nodeId] = &NSAccessLogDAOWrapper{
DAO: dao,
NodeId: nodeId,
}
accessLogLocker.Unlock()
}
accessLogDAOMapping[nodeId] = &HTTPAccessLogDAOWrapper{
DAO: dao,
NodeId: nodeId,
}
accessLogLocker.Unlock()
}
}

View File

@@ -12,13 +12,13 @@ func TestDBNodeInitializer_loop(t *testing.T) {
if err != nil {
t.Fatal(err)
}
t.Log(len(accessLogDBMapping), len(accessLogDAOMapping))
t.Log(len(accessLogDBMapping), len(httpAccessLogDAOMapping))
}
func TestFindAccessLogTable(t *testing.T) {
before := time.Now()
db := SharedHTTPAccessLogDAO.Instance
tableName, err := findAccessLogTable(db, "20201010", false)
tableName, err := findHTTPAccessLogTable(db, "20201010", false)
if err != nil {
t.Fatal(err)
}
@@ -26,7 +26,7 @@ func TestFindAccessLogTable(t *testing.T) {
t.Log(time.Since(before).Seconds()*1000, "ms")
before = time.Now()
tableName, err = findAccessLogTable(db, "20201010", false)
tableName, err = findHTTPAccessLogTable(db, "20201010", false)
if err != nil {
t.Fatal(err)
@@ -40,6 +40,6 @@ func BenchmarkFindAccessLogTable(b *testing.B) {
runtime.GOMAXPROCS(1)
for i := 0; i < b.N; i++ {
_, _ = findAccessLogTable(db, "20201010", false)
_, _ = findHTTPAccessLogTable(db, "20201010", false)
}
}

View File

@@ -2,7 +2,7 @@ package dns
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
@@ -39,7 +39,7 @@ func init() {
})
}
// 启用条目
// EnableDNSDomain 启用条目
func (this *DNSDomainDAO) EnableDNSDomain(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -48,7 +48,7 @@ func (this *DNSDomainDAO) EnableDNSDomain(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableDNSDomain 禁用条目
func (this *DNSDomainDAO) DisableDNSDomain(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -57,7 +57,7 @@ func (this *DNSDomainDAO) DisableDNSDomain(tx *dbs.Tx, id int64) error {
return err
}
// 查找启用中的条目
// FindEnabledDNSDomain 查找启用中的条目
func (this *DNSDomainDAO) FindEnabledDNSDomain(tx *dbs.Tx, id int64) (*DNSDomain, error) {
result, err := this.Query(tx).
Pk(id).
@@ -69,7 +69,7 @@ func (this *DNSDomainDAO) FindEnabledDNSDomain(tx *dbs.Tx, id int64) (*DNSDomain
return result.(*DNSDomain), err
}
// 根据主键查找名称
// FindDNSDomainName 根据主键查找名称
func (this *DNSDomainDAO) FindDNSDomainName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
@@ -77,7 +77,7 @@ func (this *DNSDomainDAO) FindDNSDomainName(tx *dbs.Tx, id int64) (string, error
FindStringCol("")
}
// 创建域名
// CreateDomain 创建域名
func (this *DNSDomainDAO) CreateDomain(tx *dbs.Tx, adminId int64, userId int64, providerId int64, name string) (int64, error) {
op := NewDNSDomainOperator()
op.ProviderId = providerId
@@ -93,7 +93,7 @@ func (this *DNSDomainDAO) CreateDomain(tx *dbs.Tx, adminId int64, userId int64,
return types.Int64(op.Id), nil
}
// 修改域名
// UpdateDomain 修改域名
func (this *DNSDomainDAO) UpdateDomain(tx *dbs.Tx, domainId int64, name string, isOn bool) error {
if domainId <= 0 {
return errors.New("invalid domainId")
@@ -109,7 +109,7 @@ func (this *DNSDomainDAO) UpdateDomain(tx *dbs.Tx, domainId int64, name string,
return nil
}
// 查询一个服务商下面的所有域名
// FindAllEnabledDomainsWithProviderId 查询一个服务商下面的所有域名
func (this *DNSDomainDAO) FindAllEnabledDomainsWithProviderId(tx *dbs.Tx, providerId int64) (result []*DNSDomain, err error) {
_, err = this.Query(tx).
State(DNSDomainStateEnabled).
@@ -120,7 +120,7 @@ func (this *DNSDomainDAO) FindAllEnabledDomainsWithProviderId(tx *dbs.Tx, provid
return
}
// 计算某个服务商下的域名数量
// CountAllEnabledDomainsWithProviderId 计算某个服务商下的域名数量
func (this *DNSDomainDAO) CountAllEnabledDomainsWithProviderId(tx *dbs.Tx, providerId int64) (int64, error) {
return this.Query(tx).
State(DNSDomainStateEnabled).
@@ -128,7 +128,7 @@ func (this *DNSDomainDAO) CountAllEnabledDomainsWithProviderId(tx *dbs.Tx, provi
Count()
}
// 更新域名数据
// UpdateDomainData 更新域名数据
func (this *DNSDomainDAO) UpdateDomainData(tx *dbs.Tx, domainId int64, data string) error {
if domainId <= 0 {
return errors.New("invalid domainId")
@@ -140,7 +140,7 @@ func (this *DNSDomainDAO) UpdateDomainData(tx *dbs.Tx, domainId int64, data stri
return err
}
// 更新域名解析记录
// UpdateDomainRecords 更新域名解析记录
func (this *DNSDomainDAO) UpdateDomainRecords(tx *dbs.Tx, domainId int64, recordsJSON []byte) error {
if domainId <= 0 {
return errors.New("invalid domainId")
@@ -153,7 +153,7 @@ func (this *DNSDomainDAO) UpdateDomainRecords(tx *dbs.Tx, domainId int64, record
return err
}
// 更新线路
// UpdateDomainRoutes 更新线路
func (this *DNSDomainDAO) UpdateDomainRoutes(tx *dbs.Tx, domainId int64, routesJSON []byte) error {
if domainId <= 0 {
return errors.New("invalid domainId")
@@ -166,8 +166,8 @@ func (this *DNSDomainDAO) UpdateDomainRoutes(tx *dbs.Tx, domainId int64, routesJ
return err
}
// 查找域名线路
func (this *DNSDomainDAO) FindDomainRoutes(tx *dbs.Tx, domainId int64) ([]*dnsclients.Route, error) {
// FindDomainRoutes 查找域名线路
func (this *DNSDomainDAO) FindDomainRoutes(tx *dbs.Tx, domainId int64) ([]*dnstypes.Route, error) {
routes, err := this.Query(tx).
Pk(domainId).
Result("routes").
@@ -178,7 +178,7 @@ func (this *DNSDomainDAO) FindDomainRoutes(tx *dbs.Tx, domainId int64) ([]*dnscl
if len(routes) == 0 || routes == "null" {
return nil, nil
}
result := []*dnsclients.Route{}
result := []*dnstypes.Route{}
err = json.Unmarshal([]byte(routes), &result)
if err != nil {
return nil, err
@@ -186,7 +186,7 @@ func (this *DNSDomainDAO) FindDomainRoutes(tx *dbs.Tx, domainId int64) ([]*dnscl
return result, nil
}
// 查找线路名称
// FindDomainRouteName 查找线路名称
func (this *DNSDomainDAO) FindDomainRouteName(tx *dbs.Tx, domainId int64, routeCode string) (string, error) {
routes, err := this.FindDomainRoutes(tx, domainId)
if err != nil {
@@ -200,7 +200,7 @@ func (this *DNSDomainDAO) FindDomainRouteName(tx *dbs.Tx, domainId int64, routeC
return "", nil
}
// 判断是否有域名可选
// ExistAvailableDomains 判断是否有域名可选
func (this *DNSDomainDAO) ExistAvailableDomains(tx *dbs.Tx) (bool, error) {
subQuery, err := SharedDNSProviderDAO.Query(tx).
Where("state=1"). // 这里要使用非变量
@@ -216,7 +216,7 @@ func (this *DNSDomainDAO) ExistAvailableDomains(tx *dbs.Tx) (bool, error) {
Exist()
}
// 检查域名解析记录是否存在
// ExistDomainRecord 检查域名解析记录是否存在
func (this *DNSDomainDAO) ExistDomainRecord(tx *dbs.Tx, domainId int64, recordName string, recordType string, recordRoute string, recordValue string) (bool, error) {
query := maps.Map{
"name": recordName,

View File

@@ -2,15 +2,15 @@ package dns
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
)
// 获取所有的线路
func (this *DNSDomain) DecodeRoutes() ([]*dnsclients.Route, error) {
// DecodeRoutes 获取所有的线路
func (this *DNSDomain) DecodeRoutes() ([]*dnstypes.Route, error) {
if len(this.Routes) == 0 || this.Routes == "null" {
return nil, nil
}
result := []*dnsclients.Route{}
result := []*dnstypes.Route{}
err := json.Unmarshal([]byte(this.Routes), &result)
if err != nil {
return nil, err
@@ -18,7 +18,7 @@ func (this *DNSDomain) DecodeRoutes() ([]*dnsclients.Route, error) {
return result, nil
}
// 检查是否包含某个线路
// ContainsRouteCode 检查是否包含某个线路
func (this *DNSDomain) ContainsRouteCode(route string) (bool, error) {
routes, err := this.DecodeRoutes()
if err != nil {
@@ -32,13 +32,13 @@ func (this *DNSDomain) ContainsRouteCode(route string) (bool, error) {
return false, nil
}
// 获取所有的记录
func (this *DNSDomain) DecodeRecords() ([]*dnsclients.Record, error) {
// DecodeRecords 获取所有的记录
func (this *DNSDomain) DecodeRecords() ([]*dnstypes.Record, error) {
records := this.Records
if len(records) == 0 || records == "null" {
return nil, nil
}
result := []*dnsclients.Record{}
result := []*dnstypes.Record{}
err := json.Unmarshal([]byte(records), &result)
if err != nil {
return nil, err

View File

@@ -9,7 +9,7 @@ import (
func TestDNSTaskDAO_CreateDNSTask(t *testing.T) {
dbs.NotifyReady()
err := SharedDNSTaskDAO.CreateDNSTask(nil, 1, 2, 3, "taskType")
err := SharedDNSTaskDAO.CreateDNSTask(nil, 1, 2, 3, 0, "taskType")
if err != nil {
t.Fatal(err)
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/types"
timeutil "github.com/iwind/TeaGo/utils/time"
"net/http"
"regexp"
"sort"
"strconv"
@@ -41,9 +42,9 @@ func NewHTTPAccessLogDAO() *HTTPAccessLogDAO {
}).(*HTTPAccessLogDAO)
}
// 创建访问日志
// CreateHTTPAccessLogs 创建访问日志
func (this *HTTPAccessLogDAO) CreateHTTPAccessLogs(tx *dbs.Tx, accessLogs []*pb.HTTPAccessLog) error {
dao := randomAccessLogDAO()
dao := randomHTTPAccessLogDAO()
if dao == nil {
dao = &HTTPAccessLogDAOWrapper{
DAO: SharedHTTPAccessLogDAO,
@@ -53,7 +54,7 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLogs(tx *dbs.Tx, accessLogs []*pb.
return this.CreateHTTPAccessLogsWithDAO(tx, dao, accessLogs)
}
// 使用特定的DAO创建访问日志
// CreateHTTPAccessLogsWithDAO 使用特定的DAO创建访问日志
func (this *HTTPAccessLogDAO) CreateHTTPAccessLogsWithDAO(tx *dbs.Tx, daoWrapper *HTTPAccessLogDAOWrapper, accessLogs []*pb.HTTPAccessLog) error {
if daoWrapper == nil {
return errors.New("dao should not be nil")
@@ -68,7 +69,7 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLogsWithDAO(tx *dbs.Tx, daoWrapper
for _, accessLog := range accessLogs {
day := timeutil.Format("Ymd", time.Unix(accessLog.Timestamp, 0))
table, err := findAccessLogTable(dao.Instance, day, false)
table, err := findHTTPAccessLogTable(dao.Instance, day, false)
if err != nil {
return err
}
@@ -97,7 +98,7 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLogsWithDAO(tx *dbs.Tx, daoWrapper
if err != nil {
// 是否为 Error 1146: Table 'xxx.xxx' doesn't exist 如果是,则创建表之后重试
if strings.Contains(err.Error(), "1146") {
table, err = findAccessLogTable(dao.Instance, day, true)
table, err = findHTTPAccessLogTable(dao.Instance, day, true)
if err != nil {
return err
}
@@ -115,8 +116,8 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLogsWithDAO(tx *dbs.Tx, daoWrapper
return nil
}
// 读取往前的 单页访问日志
func (this *HTTPAccessLogDAO) ListAccessLogs(tx *dbs.Tx, lastRequestId string, size int64, day string, serverId int64, reverse bool, hasError bool, firewallPolicyId int64, firewallRuleGroupId int64, firewallRuleSetId int64, hasFirewallPolicy bool, userId int64) (result []*HTTPAccessLog, nextLastRequestId string, hasMore bool, err error) {
// ListAccessLogs 读取往前的 单页访问日志
func (this *HTTPAccessLogDAO) ListAccessLogs(tx *dbs.Tx, lastRequestId string, size int64, day string, serverId int64, reverse bool, hasError bool, firewallPolicyId int64, firewallRuleGroupId int64, firewallRuleSetId int64, hasFirewallPolicy bool, userId int64, keyword string) (result []*HTTPAccessLog, nextLastRequestId string, hasMore bool, err error) {
if len(day) != 8 {
return
}
@@ -126,18 +127,18 @@ func (this *HTTPAccessLogDAO) ListAccessLogs(tx *dbs.Tx, lastRequestId string, s
size = 1000
}
result, nextLastRequestId, err = this.listAccessLogs(tx, lastRequestId, size, day, serverId, reverse, hasError, firewallPolicyId, firewallRuleGroupId, firewallRuleSetId, hasFirewallPolicy, userId)
result, nextLastRequestId, err = this.listAccessLogs(tx, lastRequestId, size, day, serverId, reverse, hasError, firewallPolicyId, firewallRuleGroupId, firewallRuleSetId, hasFirewallPolicy, userId, keyword)
if err != nil || int64(len(result)) < size {
return
}
moreResult, _, _ := this.listAccessLogs(tx, nextLastRequestId, 1, day, serverId, reverse, hasError, firewallPolicyId, firewallRuleGroupId, firewallRuleSetId, hasFirewallPolicy, userId)
moreResult, _, _ := this.listAccessLogs(tx, nextLastRequestId, 1, day, serverId, reverse, hasError, firewallPolicyId, firewallRuleGroupId, firewallRuleSetId, hasFirewallPolicy, userId, keyword)
hasMore = len(moreResult) > 0
return
}
// 读取往前的单页访问日志
func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx, lastRequestId string, size int64, day string, serverId int64, reverse bool, hasError bool, firewallPolicyId int64, firewallRuleGroupId int64, firewallRuleSetId int64, hasFirewallPolicy bool, userId int64) (result []*HTTPAccessLog, nextLastRequestId string, err error) {
func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx, lastRequestId string, size int64, day string, serverId int64, reverse bool, hasError bool, firewallPolicyId int64, firewallRuleGroupId int64, firewallRuleSetId int64, hasFirewallPolicy bool, userId int64, keyword string) (result []*HTTPAccessLog, nextLastRequestId string, err error) {
if size <= 0 {
return nil, lastRequestId, nil
}
@@ -155,7 +156,7 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx, lastRequestId string, s
accessLogLocker.RLock()
daoList := []*HTTPAccessLogDAOWrapper{}
for _, daoWrapper := range accessLogDAOMapping {
for _, daoWrapper := range httpAccessLogDAOMapping {
daoList = append(daoList, daoWrapper)
}
accessLogLocker.RUnlock()
@@ -178,7 +179,7 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx, lastRequestId string, s
dao := daoWrapper.DAO
tableName, exists, err := findAccessLogTableName(dao.Instance, day)
tableName, exists, err := findHTTPAccessLogTableName(dao.Instance, day)
if !exists {
// 表格不存在则跳过
return
@@ -213,6 +214,46 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx, lastRequestId string, s
query.Where("firewallPolicyId>0")
}
// keyword
if len(keyword) > 0 {
useOriginKeyword := false
where := "JSON_EXTRACT(content, '$.remoteAddr') LIKE :keyword OR JSON_EXTRACT(content, '$.requestURI') LIKE :keyword OR JSON_EXTRACT(content, '$.host') LIKE :keyword"
// 请求方法
if keyword == http.MethodGet ||
keyword == http.MethodPost ||
keyword == http.MethodHead ||
keyword == http.MethodConnect ||
keyword == http.MethodPut ||
keyword == http.MethodTrace ||
keyword == http.MethodOptions ||
keyword == http.MethodDelete ||
keyword == http.MethodPatch {
where += " OR JSON_EXTRACT(content, '$.requestMethod')=:originKeyword"
useOriginKeyword = true
}
// 响应状态码
if regexp.MustCompile(`^\d{3}$`).MatchString(keyword) {
where += " OR JSON_EXTRACT(content, '$.status')=:intKeyword"
query.Param("intKeyword", types.Int(keyword))
}
if regexp.MustCompile(`^\d{3}-\d{3}$`).MatchString(keyword) {
pieces := strings.Split(keyword, "-")
where += " OR JSON_EXTRACT(content, '$.status') BETWEEN :intKeyword1 AND :intKeyword2"
query.Param("intKeyword1", types.Int(pieces[0]))
query.Param("intKeyword2", types.Int(pieces[1]))
}
query.Where("("+where+")").
Param("keyword", "%"+keyword+"%")
if useOriginKeyword {
query.Param("originKeyword", keyword)
}
}
// offset
if len(lastRequestId) > 0 {
if !reverse {
@@ -278,7 +319,7 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx, lastRequestId string, s
}
}
// 根据请求ID获取访问日志
// FindAccessLogWithRequestId 根据请求ID获取访问日志
func (this *HTTPAccessLogDAO) FindAccessLogWithRequestId(tx *dbs.Tx, requestId string) (*HTTPAccessLog, error) {
if !regexp.MustCompile(`^\d{30,}`).MatchString(requestId) {
return nil, errors.New("invalid requestId")
@@ -286,7 +327,7 @@ func (this *HTTPAccessLogDAO) FindAccessLogWithRequestId(tx *dbs.Tx, requestId s
accessLogLocker.RLock()
daoList := []*HTTPAccessLogDAOWrapper{}
for _, daoWrapper := range accessLogDAOMapping {
for _, daoWrapper := range httpAccessLogDAOMapping {
daoList = append(daoList, daoWrapper)
}
accessLogLocker.RUnlock()
@@ -309,7 +350,7 @@ func (this *HTTPAccessLogDAO) FindAccessLogWithRequestId(tx *dbs.Tx, requestId s
dao := daoWrapper.DAO
tableName, exists, err := findAccessLogTableName(dao.Instance, day)
tableName, exists, err := findHTTPAccessLogTableName(dao.Instance, day)
if err != nil {
logs.Println("[DB_NODE]" + err.Error())
return

View File

@@ -24,7 +24,7 @@ func TestCreateHTTPAccessLogs(t *testing.T) {
Status: 200,
Timestamp: time.Now().Unix(),
}
dao := randomAccessLogDAO()
dao := randomHTTPAccessLogDAO()
t.Log("dao:", dao)
err = SharedHTTPAccessLogDAO.CreateHTTPAccessLogsWithDAO(tx, dao, []*pb.HTTPAccessLog{accessLog})
if err != nil {
@@ -41,7 +41,7 @@ func TestHTTPAccessLogDAO_ListAccessLogs(t *testing.T) {
t.Fatal(err)
}
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, "", 10, timeutil.Format("Ymd"), 0, false, false, 0, 0, 0, false, 0)
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, "", 10, timeutil.Format("Ymd"), 0, false, false, 0, 0, 0, false, 0, "")
if err != nil {
t.Fatal(err)
}
@@ -68,7 +68,7 @@ func TestHTTPAccessLogDAO_ListAccessLogs_Page(t *testing.T) {
times := 0 // 防止循环次数太多
for {
before := time.Now()
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, lastRequestId, 2, timeutil.Format("Ymd"), 0, false, false, 0, 0, 0, false, 0)
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, lastRequestId, 2, timeutil.Format("Ymd"), 0, false, false, 0, 0, 0, false, 0, "")
cost := time.Since(before).Seconds()
if err != nil {
t.Fatal(err)
@@ -99,7 +99,7 @@ func TestHTTPAccessLogDAO_ListAccessLogs_Reverse(t *testing.T) {
}
before := time.Now()
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, "16023261176446590001000000000000003500000004", 2, timeutil.Format("Ymd"), 0, true, false, 0, 0, 0, false, 0)
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, "16023261176446590001000000000000003500000004", 2, timeutil.Format("Ymd"), 0, true, false, 0, 0, 0, false, 0, "")
cost := time.Since(before).Seconds()
if err != nil {
t.Fatal(err)
@@ -124,7 +124,7 @@ func TestHTTPAccessLogDAO_ListAccessLogs_Page_NotExists(t *testing.T) {
times := 0 // 防止循环次数太多
for {
before := time.Now()
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, lastRequestId, 2, timeutil.Format("Ymd", time.Now().AddDate(0, 0, 1)), 0, false, false, 0, 0, 0, false, 0)
accessLogs, requestId, hasMore, err := SharedHTTPAccessLogDAO.ListAccessLogs(tx, lastRequestId, 2, timeutil.Format("Ymd", time.Now().AddDate(0, 0, 1)), 0, false, false, 0, 0, 0, false, 0, "")
cost := time.Since(before).Seconds()
if err != nil {
t.Fatal(err)

View File

@@ -5,7 +5,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// 转换成PB对象
// ToPB 转换成PB对象
func (this *HTTPAccessLog) ToPB() (*pb.HTTPAccessLog, error) {
p := &pb.HTTPAccessLog{}
err := json.Unmarshal([]byte(this.Content), p)

View File

@@ -0,0 +1,135 @@
package models
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
const (
HTTPAuthPolicyStateEnabled = 1 // 已启用
HTTPAuthPolicyStateDisabled = 0 // 已禁用
)
type HTTPAuthPolicyDAO dbs.DAO
func NewHTTPAuthPolicyDAO() *HTTPAuthPolicyDAO {
return dbs.NewDAO(&HTTPAuthPolicyDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeHTTPAuthPolicies",
Model: new(HTTPAuthPolicy),
PkName: "id",
},
}).(*HTTPAuthPolicyDAO)
}
var SharedHTTPAuthPolicyDAO *HTTPAuthPolicyDAO
func init() {
dbs.OnReady(func() {
SharedHTTPAuthPolicyDAO = NewHTTPAuthPolicyDAO()
})
}
// EnableHTTPAuthPolicy 启用条目
func (this *HTTPAuthPolicyDAO) EnableHTTPAuthPolicy(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", HTTPAuthPolicyStateEnabled).
Update()
return err
}
// DisableHTTPAuthPolicy 禁用条目
func (this *HTTPAuthPolicyDAO) DisableHTTPAuthPolicy(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", HTTPAuthPolicyStateDisabled).
Update()
return err
}
// FindEnabledHTTPAuthPolicy 查找启用中的条目
func (this *HTTPAuthPolicyDAO) FindEnabledHTTPAuthPolicy(tx *dbs.Tx, id int64) (*HTTPAuthPolicy, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", HTTPAuthPolicyStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*HTTPAuthPolicy), err
}
// CreateHTTPAuthPolicy 创建策略
func (this *HTTPAuthPolicyDAO) CreateHTTPAuthPolicy(tx *dbs.Tx, name string, methodType string, paramsJSON []byte) (int64, error) {
op := NewHTTPAuthPolicyOperator()
op.Name = name
op.Type = methodType
op.Params = paramsJSON
op.IsOn = true
op.State = HTTPAuthPolicyStateEnabled
return this.SaveInt64(tx, op)
}
// UpdateHTTPAuthPolicy 修改策略
func (this *HTTPAuthPolicyDAO) UpdateHTTPAuthPolicy(tx *dbs.Tx, policyId int64, name string, paramsJSON []byte, isOn bool) error {
if policyId <= 0 {
return errors.New("invalid policyId")
}
op := NewHTTPAuthPolicyOperator()
op.Id = policyId
op.Name = name
op.Params = paramsJSON
op.IsOn = isOn
err := this.Save(tx, op)
if err != nil {
return err
}
return this.NotifyUpdate(tx, policyId)
}
// ComposePolicyConfig 组合配置
func (this *HTTPAuthPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64) (*serverconfigs.HTTPAuthPolicy, error) {
policy, err := this.FindEnabledHTTPAuthPolicy(tx, policyId)
if err != nil {
return nil, err
}
if policy == nil {
return nil, nil
}
var config = &serverconfigs.HTTPAuthPolicy{
Id: int64(policy.Id),
Name: policy.Name,
IsOn: policy.IsOn == 1,
Type: policy.Type,
}
var params map[string]interface{}
if IsNotNull(policy.Params) {
err = json.Unmarshal([]byte(policy.Params), &params)
if err != nil {
return nil, err
}
config.Params = params
}
config.Params = params
return config, nil
}
// NotifyUpdate 通知更改
func (this *HTTPAuthPolicyDAO) NotifyUpdate(tx *dbs.Tx, policyId int64) error {
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithHTTPAuthPolicyId(tx, policyId)
if err != nil {
return err
}
if webId > 0 {
return SharedHTTPWebDAO.NotifyUpdate(tx, webId)
}
return nil
}

View File

@@ -0,0 +1,6 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,28 @@
package models
// HTTPAuthPolicy HTTP认证策略
type HTTPAuthPolicy struct {
Id uint64 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
UserId uint32 `field:"userId"` // 用户ID
IsOn uint8 `field:"isOn"` // 是否启用
Name string `field:"name"` // 名称
Type string `field:"type"` // 类型
Params string `field:"params"` // 参数
State uint8 `field:"state"` // 状态
}
type HTTPAuthPolicyOperator struct {
Id interface{} // ID
AdminId interface{} // 管理员ID
UserId interface{} // 用户ID
IsOn interface{} // 是否启用
Name interface{} // 名称
Type interface{} // 类型
Params interface{} // 参数
State interface{} // 状态
}
func NewHTTPAuthPolicyOperator() *HTTPAuthPolicyOperator {
return &HTTPAuthPolicyOperator{}
}

View File

@@ -0,0 +1 @@
package models

View File

@@ -111,7 +111,44 @@ func (this *HTTPCachePolicyDAO) CreateCachePolicy(tx *dbs.Tx, isOn bool, name st
if len(storageOptionsJSON) > 0 {
op.Options = storageOptionsJSON
}
err := this.Save(tx, op)
// 默认的缓存条件
cacheRef := &serverconfigs.HTTPCacheRef{
IsOn: true,
Key: "${scheme}://${host}${requestURI}",
Life: &shared.TimeDuration{Count: 2, Unit: shared.TimeDurationUnitHour},
Status: []int{200},
MaxSize: &shared.SizeCapacity{Count: 32, Unit: shared.SizeCapacityUnitMB},
SkipResponseSetCookie: true,
AllowChunkedEncoding: true,
Conds: &shared.HTTPRequestCondsConfig{
IsOn: true,
Connector: "or",
Groups: []*shared.HTTPRequestCondGroup{
{
IsOn: true,
Connector: "or",
Conds: []*shared.HTTPRequestCond{
{
Type: "url-extension",
IsRequest: true,
Param: "${requestPathExtension}",
Operator: shared.RequestCondOperatorIn,
Value: `[".html", ".js", ".css", ".gif", ".png", ".bmp", ".jpeg", ".jpg", ".webp", ".ico", ".pdf", ".ttf", ".eot", ".tiff", ".svg", ".svgz", ".eps", ".woff", ".otf", ".woff2", ".tif", ".csv", ".xls", ".xlsx", ".doc", ".docx", ".ppt", ".pptx", ".wav", ".mp3", ".mp4", ".ogg", ".mid", ".midi"]`,
},
},
Description: "初始化规则",
},
},
},
}
refsJSON, err := json.Marshal([]*serverconfigs.HTTPCacheRef{cacheRef})
if err != nil {
return 0, err
}
op.Refs = refsJSON
err = this.Save(tx, op)
if err != nil {
return 0, err
}
@@ -210,16 +247,25 @@ func (this *HTTPCachePolicyDAO) ComposeCachePolicy(tx *dbs.Tx, policyId int64) (
}
// CountAllEnabledHTTPCachePolicies 计算可用缓存策略数量
func (this *HTTPCachePolicyDAO) CountAllEnabledHTTPCachePolicies(tx *dbs.Tx) (int64, error) {
return this.Query(tx).
State(HTTPCachePolicyStateEnabled).
Count()
func (this *HTTPCachePolicyDAO) CountAllEnabledHTTPCachePolicies(tx *dbs.Tx, keyword string) (int64, error) {
query := this.Query(tx).
State(HTTPCachePolicyStateEnabled)
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
return query.Count()
}
// ListEnabledHTTPCachePolicies 列出单页的缓存策略
func (this *HTTPCachePolicyDAO) ListEnabledHTTPCachePolicies(tx *dbs.Tx, offset int64, size int64) ([]*serverconfigs.HTTPCachePolicy, error) {
ones, err := this.Query(tx).
State(HTTPCachePolicyStateEnabled).
func (this *HTTPCachePolicyDAO) ListEnabledHTTPCachePolicies(tx *dbs.Tx, keyword string, offset int64, size int64) ([]*serverconfigs.HTTPCachePolicy, error) {
query := this.Query(tx).
State(HTTPCachePolicyStateEnabled)
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
ones, err := query.
ResultPk().
Offset(offset).
Limit(size).

View File

@@ -37,12 +37,12 @@ func init() {
})
}
// 初始化
// Init 初始化
func (this *HTTPFirewallPolicyDAO) Init() {
_ = this.DAOObject.Init()
}
// 启用条目
// EnableHTTPFirewallPolicy 启用条目
func (this *HTTPFirewallPolicyDAO) EnableHTTPFirewallPolicy(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -51,7 +51,7 @@ func (this *HTTPFirewallPolicyDAO) EnableHTTPFirewallPolicy(tx *dbs.Tx, id int64
return err
}
// 禁用条目
// DisableHTTPFirewallPolicy 禁用条目
func (this *HTTPFirewallPolicyDAO) DisableHTTPFirewallPolicy(tx *dbs.Tx, policyId int64) error {
_, err := this.Query(tx).
Pk(policyId).
@@ -64,7 +64,7 @@ func (this *HTTPFirewallPolicyDAO) DisableHTTPFirewallPolicy(tx *dbs.Tx, policyI
return this.NotifyUpdate(tx, policyId)
}
// 查找启用中的条目
// FindEnabledHTTPFirewallPolicy 查找启用中的条目
func (this *HTTPFirewallPolicyDAO) FindEnabledHTTPFirewallPolicy(tx *dbs.Tx, id int64) (*HTTPFirewallPolicy, error) {
result, err := this.Query(tx).
Pk(id).
@@ -76,7 +76,7 @@ func (this *HTTPFirewallPolicyDAO) FindEnabledHTTPFirewallPolicy(tx *dbs.Tx, id
return result.(*HTTPFirewallPolicy), err
}
// 根据主键查找名称
// FindHTTPFirewallPolicyName 根据主键查找名称
func (this *HTTPFirewallPolicyDAO) FindHTTPFirewallPolicyName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
@@ -84,7 +84,7 @@ func (this *HTTPFirewallPolicyDAO) FindHTTPFirewallPolicyName(tx *dbs.Tx, id int
FindStringCol("")
}
// 查找所有可用策略
// FindAllEnabledFirewallPolicies 查找所有可用策略
func (this *HTTPFirewallPolicyDAO) FindAllEnabledFirewallPolicies(tx *dbs.Tx) (result []*HTTPFirewallPolicy, err error) {
_, err = this.Query(tx).
State(HTTPFirewallPolicyStateEnabled).
@@ -94,7 +94,7 @@ func (this *HTTPFirewallPolicyDAO) FindAllEnabledFirewallPolicies(tx *dbs.Tx) (r
return
}
// 创建策略
// CreateFirewallPolicy 创建策略
func (this *HTTPFirewallPolicyDAO) CreateFirewallPolicy(tx *dbs.Tx, userId int64, serverId int64, isOn bool, name string, description string, inboundJSON []byte, outboundJSON []byte) (int64, error) {
op := NewHTTPFirewallPolicyOperator()
op.UserId = userId
@@ -113,7 +113,7 @@ func (this *HTTPFirewallPolicyDAO) CreateFirewallPolicy(tx *dbs.Tx, userId int64
return types.Int64(op.Id), err
}
// 修改策略的Inbound和Outbound
// UpdateFirewallPolicyInboundAndOutbound 修改策略的Inbound和Outbound
func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInboundAndOutbound(tx *dbs.Tx, policyId int64, inboundJSON []byte, outboundJSON []byte) error {
if policyId <= 0 {
return errors.New("invalid policyId")
@@ -138,7 +138,7 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInboundAndOutbound(tx *db
return this.NotifyUpdate(tx, policyId)
}
// 修改策略的Inbound
// UpdateFirewallPolicyInbound 修改策略的Inbound
func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInbound(tx *dbs.Tx, policyId int64, inboundJSON []byte) error {
if policyId <= 0 {
return errors.New("invalid policyId")
@@ -158,7 +158,7 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInbound(tx *dbs.Tx, polic
return this.NotifyUpdate(tx, policyId)
}
// 修改策略
// UpdateFirewallPolicy 修改策略
func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(tx *dbs.Tx, policyId int64, isOn bool, name string, description string, inboundJSON []byte, outboundJSON []byte, blockOptionsJSON []byte) error {
if policyId <= 0 {
return errors.New("invalid policyId")
@@ -189,18 +189,28 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(tx *dbs.Tx, policyId int
return this.NotifyUpdate(tx, policyId)
}
// 计算所有可用的策略数量
func (this *HTTPFirewallPolicyDAO) CountAllEnabledFirewallPolicies(tx *dbs.Tx) (int64, error) {
return this.Query(tx).
// CountAllEnabledFirewallPolicies 计算所有可用的策略数量
func (this *HTTPFirewallPolicyDAO) CountAllEnabledFirewallPolicies(tx *dbs.Tx, keyword string) (int64, error) {
query := this.Query(tx)
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
return query.
State(HTTPFirewallPolicyStateEnabled).
Attr("userId", 0).
Attr("serverId", 0).
Count()
}
// 列出单页的策略
func (this *HTTPFirewallPolicyDAO) ListEnabledFirewallPolicies(tx *dbs.Tx, offset int64, size int64) (result []*HTTPFirewallPolicy, err error) {
_, err = this.Query(tx).
// ListEnabledFirewallPolicies 列出单页的策略
func (this *HTTPFirewallPolicyDAO) ListEnabledFirewallPolicies(tx *dbs.Tx, keyword string, offset int64, size int64) (result []*HTTPFirewallPolicy, err error) {
query := this.Query(tx)
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
_, err = query.
State(HTTPFirewallPolicyStateEnabled).
Attr("userId", 0).
Attr("serverId", 0).
@@ -212,7 +222,7 @@ func (this *HTTPFirewallPolicyDAO) ListEnabledFirewallPolicies(tx *dbs.Tx, offse
return
}
// 组合策略配置
// ComposeFirewallPolicy 组合策略配置
func (this *HTTPFirewallPolicyDAO) ComposeFirewallPolicy(tx *dbs.Tx, policyId int64) (*firewallconfigs.HTTPFirewallPolicy, error) {
policy, err := this.FindEnabledHTTPFirewallPolicy(tx, policyId)
if err != nil {
@@ -297,7 +307,7 @@ func (this *HTTPFirewallPolicyDAO) ComposeFirewallPolicy(tx *dbs.Tx, policyId in
return config, nil
}
// 检查用户防火墙策略
// CheckUserFirewallPolicy 检查用户防火墙策略
func (this *HTTPFirewallPolicyDAO) CheckUserFirewallPolicy(tx *dbs.Tx, userId int64, firewallPolicyId int64) error {
ok, err := this.Query(tx).
Pk(firewallPolicyId).
@@ -315,7 +325,7 @@ func (this *HTTPFirewallPolicyDAO) CheckUserFirewallPolicy(tx *dbs.Tx, userId in
return ErrNotFound
}
// 查找包含某个IPList的所有策略
// FindEnabledFirewallPolicyIdsWithIPListId 查找包含某个IPList的所有策略
func (this *HTTPFirewallPolicyDAO) FindEnabledFirewallPolicyIdsWithIPListId(tx *dbs.Tx, ipListId int64) ([]int64, error) {
ones, err := this.Query(tx).
ResultPk().
@@ -333,7 +343,7 @@ func (this *HTTPFirewallPolicyDAO) FindEnabledFirewallPolicyIdsWithIPListId(tx *
return result, nil
}
// 查找包含某个规则分组的策略ID
// FindEnabledFirewallPolicyIdWithRuleGroupId 查找包含某个规则分组的策略ID
func (this *HTTPFirewallPolicyDAO) FindEnabledFirewallPolicyIdWithRuleGroupId(tx *dbs.Tx, ruleGroupId int64) (int64, error) {
return this.Query(tx).
ResultPk().
@@ -343,7 +353,7 @@ func (this *HTTPFirewallPolicyDAO) FindEnabledFirewallPolicyIdWithRuleGroupId(tx
FindInt64Col(0)
}
// 设置某个策略所属的服务ID
// UpdateFirewallPolicyServerId 设置某个策略所属的服务ID
func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyServerId(tx *dbs.Tx, policyId int64, serverId int64) error {
_, err := this.Query(tx).
Pk(policyId).
@@ -352,7 +362,7 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyServerId(tx *dbs.Tx, poli
return err
}
// 通知更新
// NotifyUpdate 通知更新
func (this *HTTPFirewallPolicyDAO) NotifyUpdate(tx *dbs.Tx, policyId int64) error {
webIds, err := SharedHTTPWebDAO.FindAllWebIdsWithHTTPFirewallPolicyId(tx, policyId)
if err != nil {

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -36,12 +37,12 @@ func init() {
})
}
// 初始化
// Init 初始化
func (this *HTTPLocationDAO) Init() {
_ = this.DAOObject.Init()
}
// 启用条目
// EnableHTTPLocation 启用条目
func (this *HTTPLocationDAO) EnableHTTPLocation(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -50,7 +51,7 @@ func (this *HTTPLocationDAO) EnableHTTPLocation(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableHTTPLocation 禁用条目
func (this *HTTPLocationDAO) DisableHTTPLocation(tx *dbs.Tx, locationId int64) error {
_, err := this.Query(tx).
Pk(locationId).
@@ -62,7 +63,7 @@ func (this *HTTPLocationDAO) DisableHTTPLocation(tx *dbs.Tx, locationId int64) e
return this.NotifyUpdate(tx, locationId)
}
// 查找启用中的条目
// FindEnabledHTTPLocation 查找启用中的条目
func (this *HTTPLocationDAO) FindEnabledHTTPLocation(tx *dbs.Tx, id int64) (*HTTPLocation, error) {
result, err := this.Query(tx).
Pk(id).
@@ -74,7 +75,7 @@ func (this *HTTPLocationDAO) FindEnabledHTTPLocation(tx *dbs.Tx, id int64) (*HTT
return result.(*HTTPLocation), err
}
// 根据主键查找名称
// FindHTTPLocationName 根据主键查找名称
func (this *HTTPLocationDAO) FindHTTPLocationName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
@@ -82,8 +83,8 @@ func (this *HTTPLocationDAO) FindHTTPLocationName(tx *dbs.Tx, id int64) (string,
FindStringCol("")
}
// 创建路径规则
func (this *HTTPLocationDAO) CreateLocation(tx *dbs.Tx, parentId int64, name string, pattern string, description string, isBreak bool) (int64, error) {
// CreateLocation 创建路径规则
func (this *HTTPLocationDAO) CreateLocation(tx *dbs.Tx, parentId int64, name string, pattern string, description string, isBreak bool, condsJSON []byte) (int64, error) {
op := NewHTTPLocationOperator()
op.IsOn = true
op.State = HTTPLocationStateEnabled
@@ -92,6 +93,11 @@ func (this *HTTPLocationDAO) CreateLocation(tx *dbs.Tx, parentId int64, name str
op.Pattern = pattern
op.Description = description
op.IsBreak = isBreak
if len(condsJSON) > 0 {
op.Conds = condsJSON
}
err := this.Save(tx, op)
if err != nil {
return 0, err
@@ -99,8 +105,8 @@ func (this *HTTPLocationDAO) CreateLocation(tx *dbs.Tx, parentId int64, name str
return types.Int64(op.Id), nil
}
// 修改路径规则
func (this *HTTPLocationDAO) UpdateLocation(tx *dbs.Tx, locationId int64, name string, pattern string, description string, isOn bool, isBreak bool) error {
// UpdateLocation 修改路径规则
func (this *HTTPLocationDAO) UpdateLocation(tx *dbs.Tx, locationId int64, name string, pattern string, description string, isOn bool, isBreak bool, condsJSON []byte) error {
if locationId <= 0 {
return errors.New("invalid locationId")
}
@@ -111,6 +117,11 @@ func (this *HTTPLocationDAO) UpdateLocation(tx *dbs.Tx, locationId int64, name s
op.Description = description
op.IsOn = isOn
op.IsBreak = isBreak
if len(condsJSON) > 0 {
op.Conds = condsJSON
}
err := this.Save(tx, op)
if err != nil {
return err
@@ -118,7 +129,7 @@ func (this *HTTPLocationDAO) UpdateLocation(tx *dbs.Tx, locationId int64, name s
return this.NotifyUpdate(tx, locationId)
}
// 组合配置
// ComposeLocationConfig 组合配置
func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64) (*serverconfigs.HTTPLocationConfig, error) {
location, err := this.FindEnabledHTTPLocation(tx, locationId)
if err != nil {
@@ -163,10 +174,20 @@ func (this *HTTPLocationDAO) ComposeLocationConfig(tx *dbs.Tx, locationId int64)
}
}
// conds
if len(location.Conds) > 0 {
conds := &shared.HTTPRequestCondsConfig{}
err = json.Unmarshal([]byte(location.Conds), conds)
if err != nil {
return nil, err
}
config.Conds = conds
}
return config, nil
}
// 查找反向代理设置
// FindLocationReverseProxy 查找反向代理设置
func (this *HTTPLocationDAO) FindLocationReverseProxy(tx *dbs.Tx, locationId int64) (*serverconfigs.ReverseProxyRef, error) {
refString, err := this.Query(tx).
Pk(locationId).
@@ -186,7 +207,7 @@ func (this *HTTPLocationDAO) FindLocationReverseProxy(tx *dbs.Tx, locationId int
return nil, nil
}
// 更改反向代理设置
// UpdateLocationReverseProxy 更改反向代理设置
func (this *HTTPLocationDAO) UpdateLocationReverseProxy(tx *dbs.Tx, locationId int64, reverseProxyJSON []byte) error {
if locationId <= 0 {
return errors.New("invalid locationId")
@@ -201,7 +222,7 @@ func (this *HTTPLocationDAO) UpdateLocationReverseProxy(tx *dbs.Tx, locationId i
return this.NotifyUpdate(tx, locationId)
}
// 查找WebId
// FindLocationWebId 查找WebId
func (this *HTTPLocationDAO) FindLocationWebId(tx *dbs.Tx, locationId int64) (int64, error) {
webId, err := this.Query(tx).
Pk(locationId).
@@ -210,7 +231,7 @@ func (this *HTTPLocationDAO) FindLocationWebId(tx *dbs.Tx, locationId int64) (in
return int64(webId), err
}
// 更改Web设置
// UpdateLocationWeb 更改Web设置
func (this *HTTPLocationDAO) UpdateLocationWeb(tx *dbs.Tx, locationId int64, webId int64) error {
if locationId <= 0 {
return errors.New("invalid locationId")
@@ -225,7 +246,7 @@ func (this *HTTPLocationDAO) UpdateLocationWeb(tx *dbs.Tx, locationId int64, web
return this.NotifyUpdate(tx, locationId)
}
// 转换引用为配置
// ConvertLocationRefs 转换引用为配置
func (this *HTTPLocationDAO) ConvertLocationRefs(tx *dbs.Tx, refs []*serverconfigs.HTTPLocationRef) (locations []*serverconfigs.HTTPLocationConfig, err error) {
for _, ref := range refs {
config, err := this.ComposeLocationConfig(tx, ref.LocationId)
@@ -243,7 +264,7 @@ func (this *HTTPLocationDAO) ConvertLocationRefs(tx *dbs.Tx, refs []*serverconfi
return
}
// 根据WebId查找LocationId
// FindEnabledLocationIdWithWebId 根据WebId查找LocationId
func (this *HTTPLocationDAO) FindEnabledLocationIdWithWebId(tx *dbs.Tx, webId int64) (locationId int64, err error) {
if webId <= 0 {
return
@@ -254,7 +275,7 @@ func (this *HTTPLocationDAO) FindEnabledLocationIdWithWebId(tx *dbs.Tx, webId in
FindInt64Col(0)
}
// 通知更新
// NotifyUpdate 通知更新
func (this *HTTPLocationDAO) NotifyUpdate(tx *dbs.Tx, locationId int64) error {
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithLocationId(tx, locationId)
if err != nil {

View File

@@ -1,8 +1,10 @@
package models
import (
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -35,12 +37,12 @@ func init() {
})
}
// 初始化
// Init 初始化
func (this *HTTPRewriteRuleDAO) Init() {
_ = this.DAOObject.Init()
}
// 启用条目
// EnableHTTPRewriteRule 启用条目
func (this *HTTPRewriteRuleDAO) EnableHTTPRewriteRule(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -49,7 +51,7 @@ func (this *HTTPRewriteRuleDAO) EnableHTTPRewriteRule(tx *dbs.Tx, id int64) erro
return err
}
// 禁用条目
// DisableHTTPRewriteRule 禁用条目
func (this *HTTPRewriteRuleDAO) DisableHTTPRewriteRule(tx *dbs.Tx, rewriteRuleId int64) error {
_, err := this.Query(tx).
Pk(rewriteRuleId).
@@ -61,7 +63,7 @@ func (this *HTTPRewriteRuleDAO) DisableHTTPRewriteRule(tx *dbs.Tx, rewriteRuleId
return this.NotifyUpdate(tx, rewriteRuleId)
}
// 查找启用中的条目
// FindEnabledHTTPRewriteRule 查找启用中的条目
func (this *HTTPRewriteRuleDAO) FindEnabledHTTPRewriteRule(tx *dbs.Tx, id int64) (*HTTPRewriteRule, error) {
result, err := this.Query(tx).
Pk(id).
@@ -73,7 +75,7 @@ func (this *HTTPRewriteRuleDAO) FindEnabledHTTPRewriteRule(tx *dbs.Tx, id int64)
return result.(*HTTPRewriteRule), err
}
// 构造配置
// ComposeRewriteRule 构造配置
func (this *HTTPRewriteRuleDAO) ComposeRewriteRule(tx *dbs.Tx, rewriteRuleId int64) (*serverconfigs.HTTPRewriteRule, error) {
rule, err := this.FindEnabledHTTPRewriteRule(tx, rewriteRuleId)
if err != nil {
@@ -93,11 +95,21 @@ func (this *HTTPRewriteRuleDAO) ComposeRewriteRule(tx *dbs.Tx, rewriteRuleId int
config.ProxyHost = rule.ProxyHost
config.IsBreak = rule.IsBreak == 1
config.WithQuery = rule.WithQuery == 1
// conds
if len(rule.Conds) > 0 {
conds := &shared.HTTPRequestCondsConfig{}
err = json.Unmarshal([]byte(rule.Conds), conds)
if err != nil {
return nil, err
}
config.Conds = conds
}
return config, nil
}
// 创建规则
func (this *HTTPRewriteRuleDAO) CreateRewriteRule(tx *dbs.Tx, pattern string, replace string, mode string, redirectStatus int, isBreak bool, proxyHost string, withQuery bool, isOn bool) (int64, error) {
// 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) {
op := NewHTTPRewriteRuleOperator()
op.State = HTTPRewriteRuleStateEnabled
op.IsOn = isOn
@@ -109,12 +121,17 @@ func (this *HTTPRewriteRuleDAO) CreateRewriteRule(tx *dbs.Tx, pattern string, re
op.IsBreak = isBreak
op.WithQuery = withQuery
op.ProxyHost = proxyHost
if len(condsJSON) > 0 {
op.Conds = condsJSON
}
err := this.Save(tx, op)
return types.Int64(op.Id), err
}
// 修改规则
func (this *HTTPRewriteRuleDAO) UpdateRewriteRule(tx *dbs.Tx, rewriteRuleId int64, pattern string, replace string, mode string, redirectStatus int, isBreak bool, proxyHost string, withQuery bool, isOn bool) error {
// UpdateRewriteRule 修改规则
func (this *HTTPRewriteRuleDAO) UpdateRewriteRule(tx *dbs.Tx, rewriteRuleId int64, pattern string, replace string, mode string, redirectStatus int, isBreak bool, proxyHost string, withQuery bool, isOn bool, condsJSON []byte) error {
if rewriteRuleId <= 0 {
return errors.New("invalid rewriteRuleId")
}
@@ -128,6 +145,11 @@ func (this *HTTPRewriteRuleDAO) UpdateRewriteRule(tx *dbs.Tx, rewriteRuleId int6
op.IsBreak = isBreak
op.WithQuery = withQuery
op.ProxyHost = proxyHost
if len(condsJSON) > 0 {
op.Conds = condsJSON
}
err := this.Save(tx, op)
if err != nil {
return err
@@ -135,7 +157,7 @@ func (this *HTTPRewriteRuleDAO) UpdateRewriteRule(tx *dbs.Tx, rewriteRuleId int6
return this.NotifyUpdate(tx, rewriteRuleId)
}
// 通知更新
// NotifyUpdate 通知更新
func (this *HTTPRewriteRuleDAO) NotifyUpdate(tx *dbs.Tx, rewriteRuleId int64) error {
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithRewriteRuleId(tx, rewriteRuleId)
if err != nil {

View File

@@ -347,6 +347,27 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64) (*serverconfig
}
}
// 认证
if IsNotNull(web.Auth) {
authConfig := &serverconfigs.HTTPAuthConfig{}
err = json.Unmarshal([]byte(web.Auth), authConfig)
if err != nil {
return nil, err
}
var newRefs []*serverconfigs.HTTPAuthPolicyRef
for _, ref := range authConfig.PolicyRefs {
policyConfig, err := SharedHTTPAuthPolicyDAO.ComposePolicyConfig(tx, ref.AuthPolicyId)
if err != nil {
return nil, err
}
if policyConfig != nil {
ref.AuthPolicy = policyConfig
newRefs = append(newRefs, ref)
}
}
config.Auth = authConfig
}
return config, nil
}
@@ -622,6 +643,22 @@ func (this *HTTPWebDAO) UpdateWebRewriteRules(tx *dbs.Tx, webId int64, rewriteRu
return this.NotifyUpdate(tx, webId)
}
// UpdateWebAuth 修改认证信息
func (this *HTTPWebDAO) UpdateWebAuth(tx *dbs.Tx, webId int64, authJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.Auth = JSONBytes(authJSON)
err := this.Save(tx, op)
if err != nil {
return err
}
return this.NotifyUpdate(tx, webId)
}
// FindAllWebIdsWithCachePolicyId 根据缓存策略ID查找所有的WebId
func (this *HTTPWebDAO) FindAllWebIdsWithCachePolicyId(tx *dbs.Tx, cachePolicyId int64) ([]int64, error) {
ones, err := this.Query(tx).
@@ -783,6 +820,16 @@ func (this *HTTPWebDAO) FindEnabledWebIdWithFastcgiId(tx *dbs.Tx, fastcgiId int6
FindInt64Col(0)
}
// FindEnabledWebIdWithHTTPAuthPolicyId 查找包含某个认证策略的Web
func (this *HTTPWebDAO) FindEnabledWebIdWithHTTPAuthPolicyId(tx *dbs.Tx, httpAuthPolicyId int64) (webId int64, err error) {
return this.Query(tx).
State(HTTPWebStateEnabled).
ResultPk().
Where("JSON_CONTAINS(auth, :jsonQuery, '$.policyRefs')").
Param("jsonQuery", maps.Map{"authPolicyId": httpAuthPolicyId}.AsJSON()).
FindInt64Col(0)
}
// FindWebServerId 查找使用此Web的Server
func (this *HTTPWebDAO) FindWebServerId(tx *dbs.Tx, webId int64) (serverId int64, err error) {
if webId <= 0 {

View File

@@ -28,6 +28,7 @@ type HTTPWeb struct {
RewriteRules string `field:"rewriteRules"` // 重写规则配置
HostRedirects string `field:"hostRedirects"` // 域名跳转
Fastcgi string `field:"fastcgi"` // Fastcgi配置
Auth string `field:"auth"` // 认证策略配置
}
type HTTPWebOperator struct {
@@ -57,6 +58,7 @@ type HTTPWebOperator struct {
RewriteRules interface{} // 重写规则配置
HostRedirects interface{} // 域名跳转
Fastcgi interface{} // Fastcgi配置
Auth interface{} // 认证策略配置
}
func NewHTTPWebOperator() *HTTPWebOperator {

View File

@@ -3,6 +3,7 @@ package models
import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -112,7 +113,7 @@ func (this *MonitorNodeDAO) CreateMonitorNode(tx *dbs.Tx, name string, descripti
return 0, err
}
secret := rands.String(32)
err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, NodeRoleMonitor)
err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleMonitor)
if err != nil {
return
}

View File

@@ -0,0 +1,145 @@
package nameservers
import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
const (
NSClusterStateEnabled = 1 // 已启用
NSClusterStateDisabled = 0 // 已禁用
)
type NSClusterDAO dbs.DAO
func NewNSClusterDAO() *NSClusterDAO {
return dbs.NewDAO(&NSClusterDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNSClusters",
Model: new(NSCluster),
PkName: "id",
},
}).(*NSClusterDAO)
}
var SharedNSClusterDAO *NSClusterDAO
func init() {
dbs.OnReady(func() {
SharedNSClusterDAO = NewNSClusterDAO()
})
}
// EnableNSCluster 启用条目
func (this *NSClusterDAO) EnableNSCluster(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NSClusterStateEnabled).
Update()
return err
}
// DisableNSCluster 禁用条目
func (this *NSClusterDAO) DisableNSCluster(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NSClusterStateDisabled).
Update()
return err
}
// FindEnabledNSCluster 查找启用中的条目
func (this *NSClusterDAO) FindEnabledNSCluster(tx *dbs.Tx, id int64) (*NSCluster, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", NSClusterStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*NSCluster), err
}
// FindEnabledNSClusterName 查找启用中的条目名称
func (this *NSClusterDAO) FindEnabledNSClusterName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
State(NSClusterStateEnabled).
Result("name").
FindStringCol("")
}
// CreateCluster 创建集群
func (this *NSClusterDAO) CreateCluster(tx *dbs.Tx, name string, accessLogRefJSON []byte) (int64, error) {
op := NewNSClusterOperator()
op.Name = name
if len(accessLogRefJSON) > 0 {
op.AccessLog = accessLogRefJSON
}
op.IsOn = true
op.State = NSClusterStateEnabled
return this.SaveInt64(tx, op)
}
// UpdateCluster 修改集群
func (this *NSClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, isOn bool) error {
if clusterId <= 0 {
return errors.New("invalid clusterId")
}
op := NewNSClusterOperator()
op.Id = clusterId
op.Name = name
op.IsOn = isOn
return this.Save(tx, op)
}
// CountAllEnabledClusters 计算可用集群数量
func (this *NSClusterDAO) CountAllEnabledClusters(tx *dbs.Tx) (int64, error) {
return this.Query(tx).
State(NSClusterStateEnabled).
Count()
}
// ListEnabledClusters 列出单页集群
func (this *NSClusterDAO) ListEnabledClusters(tx *dbs.Tx, offset int64, size int64) (result []*NSCluster, err error) {
_, err = this.Query(tx).
State(NSClusterStateEnabled).
Offset(offset).
Limit(size).
DescPk().
Slice(&result).
FindAll()
return
}
// FindAllEnabledClusters 列出所有集群
func (this *NSClusterDAO) FindAllEnabledClusters(tx *dbs.Tx) (result []*NSCluster, err error) {
_, err = this.Query(tx).
State(NSClusterStateEnabled).
DescPk().
Slice(&result).
FindAll()
return
}
// UpdateClusterAccessLog 设置访问日志
func (this *NSClusterDAO) UpdateClusterAccessLog(tx *dbs.Tx, clusterId int64, accessLogJSON []byte) error {
return this.Query(tx).
Pk(clusterId).
Set("accessLog", accessLogJSON).
UpdateQuickly()
}
// FindClusterAccessLog 读取访问日志配置
func (this *NSClusterDAO) FindClusterAccessLog(tx *dbs.Tx, clusterId int64) ([]byte, error) {
accessLog, err := this.Query(tx).
Pk(clusterId).
Result("accessLog").
FindStringCol("")
return []byte(accessLog), err
}

View File

@@ -0,0 +1,6 @@
package nameservers
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,24 @@
package nameservers
// NSCluster 域名服务器集群
type NSCluster struct {
Id uint32 `field:"id"` // ID
IsOn uint8 `field:"isOn"` // 是否启用
Name string `field:"name"` // 集群名
InstallDir string `field:"installDir"` // 安装目录
State uint8 `field:"state"` // 状态
AccessLog string `field:"accessLog"` // 访问日志配置
}
type NSClusterOperator struct {
Id interface{} // ID
IsOn interface{} // 是否启用
Name interface{} // 集群名
InstallDir interface{} // 安装目录
State interface{} // 状态
AccessLog interface{} // 访问日志配置
}
func NewNSClusterOperator() *NSClusterOperator {
return &NSClusterOperator{}
}

View File

@@ -0,0 +1 @@
package nameservers

View File

@@ -0,0 +1,196 @@
package nameservers
import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
const (
NSDomainStateEnabled = 1 // 已启用
NSDomainStateDisabled = 0 // 已禁用
)
type NSDomainDAO dbs.DAO
func NewNSDomainDAO() *NSDomainDAO {
return dbs.NewDAO(&NSDomainDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNSDomains",
Model: new(NSDomain),
PkName: "id",
},
}).(*NSDomainDAO)
}
var SharedNSDomainDAO *NSDomainDAO
func init() {
dbs.OnReady(func() {
SharedNSDomainDAO = NewNSDomainDAO()
})
}
// EnableNSDomain 启用条目
func (this *NSDomainDAO) EnableNSDomain(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NSDomainStateEnabled).
Update()
return err
}
// DisableNSDomain 禁用条目
func (this *NSDomainDAO) DisableNSDomain(tx *dbs.Tx, domainId int64) error {
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
_, err = this.Query(tx).
Pk(domainId).
Set("state", NSDomainStateDisabled).
Set("version", version).
Update()
return err
}
// FindEnabledNSDomain 查找启用中的条目
func (this *NSDomainDAO) FindEnabledNSDomain(tx *dbs.Tx, id int64) (*NSDomain, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", NSDomainStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*NSDomain), err
}
// FindNSDomainName 根据主键查找名称
func (this *NSDomainDAO) FindNSDomainName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
Result("name").
FindStringCol("")
}
// CreateDomain 创建域名
func (this *NSDomainDAO) CreateDomain(tx *dbs.Tx, clusterId int64, userId int64, name string) (int64, error) {
version, err := this.IncreaseVersion(tx)
if err != nil {
return 0, err
}
op := NewNSDomainOperator()
op.ClusterId = clusterId
op.UserId = userId
op.Name = name
op.Version = version
op.IsOn = true
op.State = NSDomainStateEnabled
return this.SaveInt64(tx, op)
}
// UpdateDomain 修改域名
func (this *NSDomainDAO) UpdateDomain(tx *dbs.Tx, domainId int64, clusterId int64, userId int64, isOn bool) error {
if domainId <= 0 {
return errors.New("invalid domainId")
}
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
op := NewNSDomainOperator()
op.Id = domainId
op.ClusterId = clusterId
op.UserId = userId
op.IsOn = isOn
op.Version = version
return this.Save(tx, op)
}
// CountAllEnabledDomains 计算域名数量
func (this *NSDomainDAO) CountAllEnabledDomains(tx *dbs.Tx, clusterId int64, userId int64, keyword string) (int64, error) {
query := this.Query(tx)
if clusterId > 0 {
query.Attr("clusterId", clusterId)
} else {
query.Where("clusterId IN (SELECT id FROM " + SharedNSClusterDAO.Table + " WHERE state=1)")
}
if userId > 0 {
query.Attr("userId", userId)
} else {
query.Where("(userId=0 OR userId IN (SELECT id FROM " + models.SharedUserDAO.Table + " WHERE state=1))")
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
return query.
State(NSDomainStateEnabled).
Count()
}
// ListEnabledDomains 列出单页域名
func (this *NSDomainDAO) ListEnabledDomains(tx *dbs.Tx, clusterId int64, userId int64, keyword string, offset int64, size int64) (result []*NSDomain, err error) {
query := this.Query(tx)
if clusterId > 0 {
query.Attr("clusterId", clusterId)
} else {
query.Where("clusterId IN (SELECT id FROM " + SharedNSClusterDAO.Table + " WHERE state=1)")
}
if userId > 0 {
query.Attr("userId", userId)
} else {
query.Where("(userId=0 OR userId IN (SELECT id FROM " + models.SharedUserDAO.Table + " WHERE state=1))")
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
_, err = query.
State(NSDomainStateEnabled).
DescPk().
Offset(offset).
Limit(size).
Slice(&result).
FindAll()
return
}
// IncreaseVersion 增加版本
func (this *NSDomainDAO) IncreaseVersion(tx *dbs.Tx) (int64, error) {
return models.SharedSysLockerDAO.Increase(tx, "NS_DOMAIN_VERSION", 1)
}
// ListDomainsAfterVersion 列出某个版本后的域名
func (this *NSDomainDAO) ListDomainsAfterVersion(tx *dbs.Tx, version int64, size int64) (result []*NSDomain, err error) {
if size <= 0 {
size = 10000
}
_, err = this.Query(tx).
Gte("version", version).
Limit(size).
Asc("version").
Slice(&result).
FindAll()
return
}
// FindDomainIdWithName 根据名称查找域名
func (this *NSDomainDAO) FindDomainIdWithName(tx *dbs.Tx, clusterId int64, name string) (int64, error) {
return this.Query(tx).
Attr("clusterId", clusterId).
Attr("name", name).
State(NSDomainStateEnabled).
ResultPk().
FindInt64Col(0)
}

View File

@@ -0,0 +1,6 @@
package nameservers
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,28 @@
package nameservers
// NSDomain DNS域名
type NSDomain struct {
Id uint32 `field:"id"` // ID
ClusterId uint32 `field:"clusterId"` // 集群ID
UserId uint32 `field:"userId"` // 用户ID
IsOn uint8 `field:"isOn"` // 是否启用
Name string `field:"name"` // 域名
CreatedAt uint64 `field:"createdAt"` // 创建时间
Version uint64 `field:"version"` // 版本
State uint8 `field:"state"` // 状态
}
type NSDomainOperator struct {
Id interface{} // ID
ClusterId interface{} // 集群ID
UserId interface{} // 用户ID
IsOn interface{} // 是否启用
Name interface{} // 域名
CreatedAt interface{} // 创建时间
Version interface{} // 版本
State interface{} // 状态
}
func NewNSDomainOperator() *NSDomainOperator {
return &NSDomainOperator{}
}

View File

@@ -0,0 +1 @@
package nameservers

View File

@@ -0,0 +1,392 @@
package nameservers
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types"
)
const (
NSNodeStateEnabled = 1 // 已启用
NSNodeStateDisabled = 0 // 已禁用
)
type NSNodeDAO dbs.DAO
func NewNSNodeDAO() *NSNodeDAO {
return dbs.NewDAO(&NSNodeDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNSNodes",
Model: new(NSNode),
PkName: "id",
},
}).(*NSNodeDAO)
}
var SharedNSNodeDAO *NSNodeDAO
func init() {
dbs.OnReady(func() {
SharedNSNodeDAO = NewNSNodeDAO()
})
}
// EnableNSNode 启用条目
func (this *NSNodeDAO) EnableNSNode(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NSNodeStateEnabled).
Update()
return err
}
// DisableNSNode 禁用条目
func (this *NSNodeDAO) DisableNSNode(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NSNodeStateDisabled).
Update()
if err != nil {
return err
}
return this.NotifyUpdate(tx, id)
}
// FindEnabledNSNode 查找启用中的条目
func (this *NSNodeDAO) FindEnabledNSNode(tx *dbs.Tx, id int64) (*NSNode, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", NSNodeStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*NSNode), err
}
// FindAllEnabledNodesWithClusterId 查找一个集群下的所有节点
func (this *NSNodeDAO) FindAllEnabledNodesWithClusterId(tx *dbs.Tx, clusterId int64) (result []*NSNode, err error) {
_, err = this.Query(tx).
Attr("clusterId", clusterId).
State(NSNodeStateEnabled).
DescPk().
Slice(&result).
FindAll()
return
}
// CountAllEnabledNodes 所有集群的可用的节点数量
func (this *NSNodeDAO) CountAllEnabledNodes(tx *dbs.Tx) (int64, error) {
return this.Query(tx).
State(NSNodeStateEnabled).
Where("clusterId IN (SELECT id FROM " + SharedNSClusterDAO.Table + " WHERE state=1)").
Count()
}
// CountAllEnabledNodesMatch 计算满足条件的节点数量
func (this *NSNodeDAO) CountAllEnabledNodesMatch(tx *dbs.Tx, clusterId int64, installState configutils.BoolState, activeState configutils.BoolState, keyword string) (int64, error) {
query := this.Query(tx)
if clusterId > 0 {
query.Attr("clusterId", clusterId)
}
// 安装状态
switch installState {
case configutils.BoolStateAll:
// 所有
case configutils.BoolStateYes:
query.Attr("isInstalled", 1)
case configutils.BoolStateNo:
query.Attr("isInstalled", 0)
}
// 在线状态
switch activeState {
case configutils.BoolStateAll:
// 所有
case configutils.BoolStateYes:
query.Where("JSON_EXTRACT(status, '$.isActive') AND UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')<=60")
case configutils.BoolStateNo:
query.Where("(status IS NULL OR NOT JSON_EXTRACT(status, '$.isActive') OR UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>60)")
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
return query.
State(NSNodeStateEnabled).
Count()
}
// ListAllEnabledNodesMatch 列出单页匹配的节点
func (this *NSNodeDAO) ListAllEnabledNodesMatch(tx *dbs.Tx, clusterId int64, installState configutils.BoolState, activeState configutils.BoolState, keyword string, offset int64, size int64) (result []*NSNode, err error) {
query := this.Query(tx)
// 安装状态
switch installState {
case configutils.BoolStateAll:
// 所有
case configutils.BoolStateYes:
query.Attr("isInstalled", 1)
case configutils.BoolStateNo:
query.Attr("isInstalled", 0)
}
// 在线状态
switch activeState {
case configutils.BoolStateAll:
// 所有
case configutils.BoolStateYes:
query.Where("JSON_EXTRACT(status, '$.isActive') AND UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')<=60")
case configutils.BoolStateNo:
query.Where("(status IS NULL OR NOT JSON_EXTRACT(status, '$.isActive') OR UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>60)")
}
if clusterId > 0 {
query.Attr("clusterId", clusterId)
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
_, err = query.
State(NSNodeStateEnabled).
Offset(offset).
Limit(size).
Slice(&result).
DescPk().
FindAll()
return
}
// CountAllLowerVersionNodesWithClusterId 计算单个集群中所有低于某个版本的节点数量
func (this *NSNodeDAO) CountAllLowerVersionNodesWithClusterId(tx *dbs.Tx, clusterId int64, os string, arch string, version string) (int64, error) {
return this.Query(tx).
State(NSNodeStateEnabled).
Attr("clusterId", clusterId).
Where("status IS NOT NULL").
Where("JSON_EXTRACT(status, '$.os')=:os").
Where("JSON_EXTRACT(status, '$.arch')=:arch").
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
Param("os", os).
Param("arch", arch).
Param("version", utils.VersionToLong(version)).
Count()
}
// CreateNode 创建节点
func (this *NSNodeDAO) CreateNode(tx *dbs.Tx, adminId int64, name string, clusterId int64) (nodeId int64, err error) {
uniqueId, err := this.GenUniqueId(tx)
if err != nil {
return 0, err
}
secret := rands.String(32)
// 保存API Token
err = models.SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleDNS)
if err != nil {
return
}
op := NewNSNodeOperator()
op.AdminId = adminId
op.Name = name
op.UniqueId = uniqueId
op.Secret = secret
op.ClusterId = clusterId
op.IsOn = 1
op.State = NSNodeStateEnabled
err = this.Save(tx, op)
if err != nil {
return 0, err
}
// 通知节点更新
nodeId = types.Int64(op.Id)
err = this.NotifyUpdate(tx, nodeId)
if err != nil {
return 0, err
}
// 通知DNS更新
err = this.NotifyDNSUpdate(tx, nodeId)
if err != nil {
return 0, err
}
return nodeId, nil
}
// UpdateNode 修改节点
func (this *NSNodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, clusterId int64, isOn bool) error {
if nodeId <= 0 {
return errors.New("invalid nodeId")
}
op := NewNSNodeOperator()
op.Id = nodeId
op.Name = name
op.ClusterId = clusterId
op.IsOn = isOn
err := this.Save(tx, op)
if err != nil {
return err
}
err = this.NotifyUpdate(tx, nodeId)
if err != nil {
return err
}
return this.NotifyDNSUpdate(tx, nodeId)
}
// FindEnabledNodeIdWithUniqueId 根据唯一ID获取节点ID
func (this *NSNodeDAO) FindEnabledNodeIdWithUniqueId(tx *dbs.Tx, uniqueId string) (int64, error) {
return this.Query(tx).
Attr("uniqueId", uniqueId).
Attr("state", NSNodeStateEnabled).
ResultPk().
FindInt64Col(0)
}
// FindNodeInstallStatus 查询节点的安装状态
func (this *NSNodeDAO) FindNodeInstallStatus(tx *dbs.Tx, nodeId int64) (*models.NodeInstallStatus, error) {
node, err := this.Query(tx).
Pk(nodeId).
Result("installStatus", "isInstalled").
Find()
if err != nil {
return nil, err
}
if node == nil {
return nil, errors.New("not found")
}
installStatus := node.(*NSNode).InstallStatus
isInstalled := node.(*NSNode).IsInstalled == 1
if len(installStatus) == 0 {
return models.NewNodeInstallStatus(), nil
}
status := &models.NodeInstallStatus{}
err = json.Unmarshal([]byte(installStatus), status)
if err != nil {
return nil, err
}
if isInstalled {
status.IsFinished = true
status.IsOk = true
}
return status, nil
}
// GenUniqueId 生成唯一ID
func (this *NSNodeDAO) GenUniqueId(tx *dbs.Tx) (string, error) {
for {
uniqueId := rands.HexString(32)
ok, err := this.Query(tx).
Attr("uniqueId", uniqueId).
Exist()
if err != nil {
return "", err
}
if ok {
continue
}
return uniqueId, nil
}
}
// UpdateNodeIsInstalled 设置节点安装状态
func (this *NSNodeDAO) UpdateNodeIsInstalled(tx *dbs.Tx, nodeId int64, isInstalled bool) error {
_, err := this.Query(tx).
Pk(nodeId).
Set("isInstalled", isInstalled).
Set("installStatus", "null"). // 重置安装状态
Update()
return err
}
// UpdateNodeStatus 更改节点状态
func (this NSNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, statusJSON []byte) error {
if statusJSON == nil {
return nil
}
_, err := this.Query(tx).
Pk(nodeId).
Set("status", string(statusJSON)).
Update()
return err
}
// CountAllLowerVersionNodes 计算所有节点中低于某个版本的节点数量
func (this *NSNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
return this.Query(tx).
State(NSNodeStateEnabled).
Where("status IS NOT NULL").
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
Param("version", utils.VersionToLong(version)).
Count()
}
// ComposeNodeConfig 组合节点配置
func (this *NSNodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64) (*dnsconfigs.NSNodeConfig, error) {
if nodeId <= 0 {
return nil, nil
}
node, err := this.FindEnabledNSNode(tx, nodeId)
if err != nil {
return nil, err
}
if node == nil {
return nil, nil
}
cluster, err := SharedNSClusterDAO.FindEnabledNSCluster(tx, int64(node.ClusterId))
if err != nil {
return nil, err
}
if cluster == nil {
return nil, nil
}
config := &dnsconfigs.NSNodeConfig{
Id: int64(node.Id),
ClusterId: int64(node.ClusterId),
}
if len(cluster.AccessLog) > 0 {
ref := &dnsconfigs.AccessLogRef{}
err = json.Unmarshal([]byte(cluster.AccessLog), ref)
if err != nil {
return nil, err
}
config.AccessLogRef = ref
}
return config, nil
}
// NotifyUpdate 通知更新
func (this *NSNodeDAO) NotifyUpdate(tx *dbs.Tx, nodeId int64) error {
// TODO 先什么都不做
return nil
}
// NotifyDNSUpdate 通知DNS更新
func (this *NSNodeDAO) NotifyDNSUpdate(tx *dbs.Tx, nodeId int64) error {
// TODO 先什么都不做
return nil
}

View File

@@ -0,0 +1,6 @@
package nameservers
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,38 @@
package nameservers
// NSNode 域名服务器节点
type NSNode struct {
Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
ClusterId uint32 `field:"clusterId"` // 集群ID
Name string `field:"name"` // 节点名称
IsOn uint8 `field:"isOn"` // 是否启用
Status string `field:"status"` // 运行状态
UniqueId string `field:"uniqueId"` // 节点ID
Secret string `field:"secret"` // 密钥
IsUp uint8 `field:"isUp"` // 是否运行
IsInstalled uint8 `field:"isInstalled"` // 是否已安装
InstallStatus string `field:"installStatus"` // 安装状态
InstallDir string `field:"installDir"` // 安装目录
State uint8 `field:"state"` // 状态
}
type NSNodeOperator struct {
Id interface{} // ID
AdminId interface{} // 管理员ID
ClusterId interface{} // 集群ID
Name interface{} // 节点名称
IsOn interface{} // 是否启用
Status interface{} // 运行状态
UniqueId interface{} // 节点ID
Secret interface{} // 密钥
IsUp interface{} // 是否运行
IsInstalled interface{} // 是否已安装
InstallStatus interface{} // 安装状态
InstallDir interface{} // 安装目录
State interface{} // 状态
}
func NewNSNodeOperator() *NSNodeOperator {
return &NSNodeOperator{}
}

View File

@@ -0,0 +1,42 @@
package nameservers
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"time"
)
// DecodeInstallStatus 安装状态
func (this *NSNode) DecodeInstallStatus() (*models.NodeInstallStatus, error) {
if len(this.InstallStatus) == 0 || this.InstallStatus == "null" {
return models.NewNodeInstallStatus(), nil
}
status := &models.NodeInstallStatus{}
err := json.Unmarshal([]byte(this.InstallStatus), status)
if err != nil {
return models.NewNodeInstallStatus(), err
}
// 如果N秒钟没有更新状态则认为不在运行
if status.IsRunning && status.UpdatedAt < time.Now().Unix()-10 {
status.IsRunning = false
status.IsFinished = true
status.Error = "timeout"
}
return status, nil
}
// DecodeStatus 节点状态
func (this *NSNode) DecodeStatus() (*nodeconfigs.NodeStatus, error) {
if len(this.Status) == 0 || this.Status == "null" {
return nil, nil
}
status := &nodeconfigs.NodeStatus{}
err := json.Unmarshal([]byte(this.Status), status)
if err != nil {
return nil, err
}
return status, nil
}

View File

@@ -0,0 +1,220 @@
package nameservers
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"strconv"
)
const (
NSRecordStateEnabled = 1 // 已启用
NSRecordStateDisabled = 0 // 已禁用
)
type NSRecordDAO dbs.DAO
func NewNSRecordDAO() *NSRecordDAO {
return dbs.NewDAO(&NSRecordDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNSRecords",
Model: new(NSRecord),
PkName: "id",
},
}).(*NSRecordDAO)
}
var SharedNSRecordDAO *NSRecordDAO
func init() {
dbs.OnReady(func() {
SharedNSRecordDAO = NewNSRecordDAO()
})
}
// EnableNSRecord 启用条目
func (this *NSRecordDAO) EnableNSRecord(tx *dbs.Tx, id uint64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NSRecordStateEnabled).
Update()
return err
}
// DisableNSRecord 禁用条目
func (this *NSRecordDAO) DisableNSRecord(tx *dbs.Tx, id int64) error {
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
_, err = this.Query(tx).
Pk(id).
Set("state", NSRecordStateDisabled).
Set("version", version).
Update()
return err
}
// FindEnabledNSRecord 查找启用中的条目
func (this *NSRecordDAO) FindEnabledNSRecord(tx *dbs.Tx, id int64) (*NSRecord, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", NSRecordStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*NSRecord), err
}
// FindNSRecordName 根据主键查找名称
func (this *NSRecordDAO) FindNSRecordName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
Result("name").
FindStringCol("")
}
// CreateRecord 创建记录
func (this *NSRecordDAO) CreateRecord(tx *dbs.Tx, domainId int64, description string, name string, dnsType dnsconfigs.RecordType, value string, ttl int32, routeIds []int64) (int64, error) {
version, err := this.IncreaseVersion(tx)
if err != nil {
return 0, err
}
op := NewNSRecordOperator()
op.DomainId = domainId
op.Description = description
op.Name = name
op.Type = dnsType
op.Value = value
op.Ttl = ttl
if len(routeIds) == 0 {
op.RouteIds = "[]"
} else {
routeIds, err := json.Marshal(routeIds)
if err != nil {
return 0, err
}
op.RouteIds = routeIds
}
op.IsOn = true
op.State = NSRecordStateEnabled
op.Version = version
return this.SaveInt64(tx, op)
}
func (this *NSRecordDAO) UpdateRecord(tx *dbs.Tx, recordId int64, description string, name string, dnsType dnsconfigs.RecordType, value string, ttl int32, routeIds []int64) error {
if recordId <= 0 {
return errors.New("invalid recordId")
}
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
op := NewNSRecordOperator()
op.Id = recordId
op.Description = description
op.Name = name
op.Type = dnsType
op.Value = value
op.Ttl = ttl
if len(routeIds) == 0 {
op.RouteIds = "[]"
} else {
routeIds, err := json.Marshal(routeIds)
if err != nil {
return err
}
op.RouteIds = routeIds
}
op.Version = version
return this.Save(tx, op)
}
func (this *NSRecordDAO) CountAllEnabledRecords(tx *dbs.Tx, domainId int64, dnsType dnsconfigs.RecordType, keyword string, routeId int64) (int64, error) {
query := this.Query(tx).
Attr("domainId", domainId).
State(NSRecordStateEnabled)
if len(dnsType) > 0 {
query.Attr("type", dnsType)
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword OR value LIKE :keyword OR description LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
if routeId > 0 {
query.JSONContains("routeIds", strconv.FormatInt(routeId, 10))
}
return query.Count()
}
func (this *NSRecordDAO) ListEnabledRecords(tx *dbs.Tx, domainId int64, dnsType dnsconfigs.RecordType, keyword string, routeId int64, offset int64, size int64) (result []*NSRecord, err error) {
query := this.Query(tx).
Attr("domainId", domainId).
State(NSRecordStateEnabled)
if len(dnsType) > 0 {
query.Attr("type", dnsType)
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword OR value LIKE :keyword OR description LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
if routeId > 0 {
query.JSONContains("routeIds", strconv.FormatInt(routeId, 10))
}
_, err = query.
DescPk().
Offset(offset).
Limit(size).
Slice(&result).
FindAll()
return
}
// IncreaseVersion 增加版本
func (this *NSRecordDAO) IncreaseVersion(tx *dbs.Tx) (int64, error) {
return models.SharedSysLockerDAO.Increase(tx, "NS_RECORD_VERSION", 1)
}
// ListRecordsAfterVersion 列出某个版本后的记录
func (this *NSRecordDAO) ListRecordsAfterVersion(tx *dbs.Tx, version int64, size int64) (result []*NSRecord, err error) {
if size <= 0 {
size = 10000
}
_, err = this.Query(tx).
Gte("version", version).
Limit(size).
Asc("version").
Slice(&result).
FindAll()
return
}
// FindEnabledRecordWithName 查询单条记录
func (this *NSRecordDAO) FindEnabledRecordWithName(tx *dbs.Tx, domainId int64, recordName string, recordType dnsconfigs.RecordType) (*NSRecord, error) {
record, err := this.Query(tx).
State(NSRecordStateEnabled).
Attr("domainId", domainId).
Attr("name", recordName).
Attr("type", recordType).
Find()
if record == nil {
return nil, err
}
return record.(*NSRecord), nil
}

View File

@@ -0,0 +1,6 @@
package nameservers
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,38 @@
package nameservers
// NSRecord DNS记录
type NSRecord struct {
Id uint64 `field:"id"` // ID
DomainId uint32 `field:"domainId"` // 域名ID
IsOn uint8 `field:"isOn"` // 是否启用
Description string `field:"description"` // 备注
Name string `field:"name"` // 记录名
Type string `field:"type"` // 类型
Value string `field:"value"` // 值
Ttl uint32 `field:"ttl"` // TTL
Weight uint32 `field:"weight"` // 权重
RouteIds string `field:"routeIds"` // 线路
CreatedAt uint64 `field:"createdAt"` // 创建时间
Version uint64 `field:"version"` //
State uint8 `field:"state"` // 状态
}
type NSRecordOperator struct {
Id interface{} // ID
DomainId interface{} // 域名ID
IsOn interface{} // 是否启用
Description interface{} // 备注
Name interface{} // 记录名
Type interface{} // 类型
Value interface{} // 值
Ttl interface{} // TTL
Weight interface{} // 权重
RouteIds interface{} // 线路
CreatedAt interface{} // 创建时间
Version interface{} //
State interface{} // 状态
}
func NewNSRecordOperator() *NSRecordOperator {
return &NSRecordOperator{}
}

View File

@@ -0,0 +1,11 @@
package nameservers
import "encoding/json"
func (this *NSRecord) DecodeRouteIds() []int64 {
routeIds := []int64{}
if len(this.RouteIds) > 0 {
_ = json.Unmarshal([]byte(this.RouteIds), &routeIds)
}
return routeIds
}

View File

@@ -0,0 +1,192 @@
package nameservers
import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
const (
NSRouteStateEnabled = 1 // 已启用
NSRouteStateDisabled = 0 // 已禁用
)
type NSRouteDAO dbs.DAO
func NewNSRouteDAO() *NSRouteDAO {
return dbs.NewDAO(&NSRouteDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNSRoutes",
Model: new(NSRoute),
PkName: "id",
},
}).(*NSRouteDAO)
}
var SharedNSRouteDAO *NSRouteDAO
func init() {
dbs.OnReady(func() {
SharedNSRouteDAO = NewNSRouteDAO()
})
}
// EnableNSRoute 启用条目
func (this *NSRouteDAO) EnableNSRoute(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NSRouteStateEnabled).
Update()
return err
}
// DisableNSRoute 禁用条目
func (this *NSRouteDAO) DisableNSRoute(tx *dbs.Tx, routeId int64) error {
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
_, err = this.Query(tx).
Pk(routeId).
Set("state", NSRouteStateDisabled).
Set("version", version).
Update()
return err
}
// FindEnabledNSRoute 查找启用中的条目
func (this *NSRouteDAO) FindEnabledNSRoute(tx *dbs.Tx, id int64) (*NSRoute, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", NSRouteStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*NSRoute), err
}
// FindNSRouteName 根据主键查找名称
func (this *NSRouteDAO) FindNSRouteName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
Result("name").
FindStringCol("")
}
// CreateRoute 创建线路
func (this *NSRouteDAO) CreateRoute(tx *dbs.Tx, clusterId int64, domainId int64, userId int64, name string, rangesJSON []byte) (int64, error) {
version, err := this.IncreaseVersion(tx)
if err != nil {
return 0, err
}
op := NewNSRouteOperator()
op.ClusterId = clusterId
op.DomainId = domainId
op.UserId = userId
op.Name = name
if len(rangesJSON) > 0 {
op.Ranges = rangesJSON
} else {
op.Ranges = "[]"
}
op.IsOn = true
op.State = NSRouteStateEnabled
op.Version = version
return this.SaveInt64(tx, op)
}
// UpdateRoute 修改线路
func (this *NSRouteDAO) UpdateRoute(tx *dbs.Tx, routeId int64, name string, rangesJSON []byte) error {
if routeId <= 0 {
return errors.New("invalid routeId")
}
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
op := NewNSRouteOperator()
op.Id = routeId
op.Name = name
if len(rangesJSON) > 0 {
op.Ranges = rangesJSON
} else {
op.Ranges = "[]"
}
op.Version = version
return this.Save(tx, op)
}
// UpdateRouteOrders 修改线路排序
func (this *NSRouteDAO) UpdateRouteOrders(tx *dbs.Tx, routeIds []int64) error {
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
order := len(routeIds)
for _, routeId := range routeIds {
_, err = this.Query(tx).
Pk(routeId).
Set("order", order).
Set("version", version).
Update()
if err != nil {
return err
}
order--
}
return nil
}
// FindAllEnabledRoutes 列出所有线路
func (this *NSRouteDAO) FindAllEnabledRoutes(tx *dbs.Tx, clusterId int64, domainId int64, userId int64) (result []*NSRoute, err error) {
query := this.Query(tx).
State(NSRouteStateEnabled).
Slice(&result).
Desc("order").
DescPk()
if clusterId > 0 {
query.Attr("clusterId", clusterId)
} else {
// 不查询所有集群的线路
query.Attr("clusterId", 0)
}
if domainId > 0 {
query.Attr("domainId", domainId)
}
if userId > 0 {
query.Attr("userId", userId)
}
_, err = query.FindAll()
return
}
// IncreaseVersion 增加版本
func (this *NSRouteDAO) IncreaseVersion(tx *dbs.Tx) (int64, error) {
return models.SharedSysLockerDAO.Increase(tx, "NS_ROUTE_VERSION", 1)
}
// ListRoutesAfterVersion 列出某个版本后的域名
func (this *NSRouteDAO) ListRoutesAfterVersion(tx *dbs.Tx, version int64, size int64) (result []*NSRoute, err error) {
if size <= 0 {
size = 10000
}
_, err = this.Query(tx).
Gte("version", version).
Limit(size).
Asc("version").
Slice(&result).
FindAll()
return
}

View File

@@ -0,0 +1,6 @@
package nameservers
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,32 @@
package nameservers
// NSRoute DNS线路
type NSRoute struct {
Id uint32 `field:"id"` // ID
IsOn uint8 `field:"isOn"` // 是否启用
ClusterId uint32 `field:"clusterId"` // 集群ID
DomainId uint32 `field:"domainId"` // 域名ID
UserId uint32 `field:"userId"` // 用户ID
Name string `field:"name"` // 名称
Ranges string `field:"ranges"` // 范围
Order uint32 `field:"order"` // 排序
Version uint64 `field:"version"` // 版本号
State uint8 `field:"state"` // 状态
}
type NSRouteOperator struct {
Id interface{} // ID
IsOn interface{} // 是否启用
ClusterId interface{} // 集群ID
DomainId interface{} // 域名ID
UserId interface{} // 用户ID
Name interface{} // 名称
Ranges interface{} // 范围
Order interface{} // 排序
Version interface{} // 版本号
State interface{} // 状态
}
func NewNSRouteOperator() *NSRouteOperator {
return &NSRouteOperator{}
}

View File

@@ -0,0 +1 @@
package nameservers

View File

@@ -126,7 +126,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
}
secret := rands.String(32)
err = SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, NodeRoleCluster)
err = SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleCluster)
if err != nil {
return 0, err
}
@@ -549,7 +549,7 @@ func (this *NodeClusterDAO) CheckClusterDNS(tx *dbs.Tx, cluster *NodeCluster) (i
}
// 检查IP地址
ipAddr, err := SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddress(tx, nodeId)
ipAddr, err := SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddress(tx, nodeId, nodeconfigs.NodeRoleNode)
if err != nil {
return nil, err
}

View File

@@ -125,7 +125,7 @@ func (this *NodeDAO) CreateNode(tx *dbs.Tx, adminId int64, name string, clusterI
secret := rands.String(32)
// 保存API Token
err = SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, NodeRoleNode)
err = SharedApiTokenDAO.CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleNode)
if err != nil {
return
}
@@ -402,6 +402,27 @@ func (this *NodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, statusJSON []byt
return err
}
// FindNodeStatus 获取节点状态
func (this *NodeDAO) FindNodeStatus(tx *dbs.Tx, nodeId int64) (*nodeconfigs.NodeStatus, error) {
statusJSONString, err := this.Query(tx).
Pk(nodeId).
Result("status").
FindStringCol("")
if err != nil {
return nil, err
}
if len(statusJSONString) == 0 {
return nil, nil
}
status := &nodeconfigs.NodeStatus{}
err = json.Unmarshal([]byte(statusJSONString), status)
if err != nil {
return nil, err
}
return status, nil
}
// UpdateNodeIsActive 更改节点在线状态
func (this *NodeDAO) UpdateNodeIsActive(tx *dbs.Tx, nodeId int64, isActive bool) error {
b := "true"

View File

@@ -2,6 +2,7 @@ package models
import (
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -34,7 +35,7 @@ func init() {
})
}
// 启用条目
// EnableAddress 启用条目
func (this *NodeIPAddressDAO) EnableAddress(tx *dbs.Tx, id int64) (err error) {
_, err = this.Query(tx).
Pk(id).
@@ -43,7 +44,7 @@ func (this *NodeIPAddressDAO) EnableAddress(tx *dbs.Tx, id int64) (err error) {
return err
}
// 禁用IP地址
// DisableAddress 禁用IP地址
func (this *NodeIPAddressDAO) DisableAddress(tx *dbs.Tx, id int64) (err error) {
_, err = this.Query(tx).
Pk(id).
@@ -52,11 +53,14 @@ func (this *NodeIPAddressDAO) DisableAddress(tx *dbs.Tx, id int64) (err error) {
return err
}
// 禁用节点的所有的IP地址
func (this *NodeIPAddressDAO) DisableAllAddressesWithNodeId(tx *dbs.Tx, nodeId int64) error {
// DisableAllAddressesWithNodeId 禁用节点的所有的IP地址
func (this *NodeIPAddressDAO) DisableAllAddressesWithNodeId(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) error {
if nodeId <= 0 {
return errors.New("invalid nodeId")
}
if len(role) == 0 {
role = nodeconfigs.NodeRoleNode
}
_, err := this.Query(tx).
Attr("nodeId", nodeId).
Set("state", NodeIPAddressStateDisabled).
@@ -64,7 +68,7 @@ func (this *NodeIPAddressDAO) DisableAllAddressesWithNodeId(tx *dbs.Tx, nodeId i
return err
}
// 查找启用中的IP地址
// FindEnabledAddress 查找启用中的IP地址
func (this *NodeIPAddressDAO) FindEnabledAddress(tx *dbs.Tx, id int64) (*NodeIPAddress, error) {
result, err := this.Query(tx).
Pk(id).
@@ -76,7 +80,7 @@ func (this *NodeIPAddressDAO) FindEnabledAddress(tx *dbs.Tx, id int64) (*NodeIPA
return result.(*NodeIPAddress), err
}
// 根据主键查找名称
// FindAddressName 根据主键查找名称
func (this *NodeIPAddressDAO) FindAddressName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
@@ -84,10 +88,15 @@ func (this *NodeIPAddressDAO) FindAddressName(tx *dbs.Tx, id int64) (string, err
FindStringCol("")
}
// 创建IP地址
func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, nodeId int64, name string, ip string, canAccess bool) (addressId int64, err error) {
// CreateAddress 创建IP地址
func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole, name string, ip string, canAccess bool) (addressId int64, err error) {
if len(role) == 0 {
role = nodeconfigs.NodeRoleNode
}
op := NewNodeIPAddressOperator()
op.NodeId = nodeId
op.Role = role
op.Name = name
op.Ip = ip
op.CanAccess = canAccess
@@ -105,7 +114,7 @@ func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, nodeId int64, name strin
return types.Int64(op.Id), nil
}
// 修改IP地址
// UpdateAddress 修改IP地址
func (this *NodeIPAddressDAO) UpdateAddress(tx *dbs.Tx, addressId int64, name string, ip string, canAccess bool) (err error) {
if addressId <= 0 {
return errors.New("invalid addressId")
@@ -121,7 +130,7 @@ func (this *NodeIPAddressDAO) UpdateAddress(tx *dbs.Tx, addressId int64, name st
return err
}
// 修改IP地址中的IP
// UpdateAddressIP 修改IP地址中的IP
func (this *NodeIPAddressDAO) UpdateAddressIP(tx *dbs.Tx, addressId int64, ip string) error {
if addressId <= 0 {
return errors.New("invalid addressId")
@@ -133,7 +142,7 @@ func (this *NodeIPAddressDAO) UpdateAddressIP(tx *dbs.Tx, addressId int64, ip st
return err
}
// 修改IP地址所属节点
// UpdateAddressNodeId 修改IP地址所属节点
func (this *NodeIPAddressDAO) UpdateAddressNodeId(tx *dbs.Tx, addressId int64, nodeId int64) error {
_, err := this.Query(tx).
Pk(addressId).
@@ -151,10 +160,14 @@ func (this *NodeIPAddressDAO) UpdateAddressNodeId(tx *dbs.Tx, addressId int64, n
return nil
}
// 查找节点的所有的IP地址
func (this *NodeIPAddressDAO) FindAllEnabledAddressesWithNode(tx *dbs.Tx, nodeId int64) (result []*NodeIPAddress, err error) {
// FindAllEnabledAddressesWithNode 查找节点的所有的IP地址
func (this *NodeIPAddressDAO) FindAllEnabledAddressesWithNode(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (result []*NodeIPAddress, err error) {
if len(role) == 0 {
role = nodeconfigs.NodeRoleNode
}
_, err = this.Query(tx).
Attr("nodeId", nodeId).
Attr("role", role).
State(NodeIPAddressStateEnabled).
Desc("order").
AscPk().
@@ -163,10 +176,14 @@ func (this *NodeIPAddressDAO) FindAllEnabledAddressesWithNode(tx *dbs.Tx, nodeId
return
}
// 查找节点的第一个可访问的IP地址
func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId int64) (string, error) {
// FindFirstNodeAccessIPAddress 查找节点的第一个可访问的IP地址
func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (string, error) {
if len(role) == 0 {
role = nodeconfigs.NodeRoleNode
}
return this.Query(tx).
Attr("nodeId", nodeId).
Attr("role", role).
State(NodeIPAddressStateEnabled).
Attr("canAccess", true).
Desc("order").
@@ -175,10 +192,14 @@ func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId in
FindStringCol("")
}
// 查找节点的第一个可访问的IP地址ID
func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddressId(tx *dbs.Tx, nodeId int64) (int64, error) {
// FindFirstNodeAccessIPAddressId 查找节点的第一个可访问的IP地址ID
func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddressId(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (int64, error) {
if len(role) == 0 {
role = nodeconfigs.NodeRoleNode
}
return this.Query(tx).
Attr("nodeId", nodeId).
Attr("role", role).
State(NodeIPAddressStateEnabled).
Attr("canAccess", true).
Desc("order").
@@ -187,8 +208,11 @@ func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddressId(tx *dbs.Tx, nodeId
FindInt64Col(0)
}
// 查找节点所有的可访问的IP地址
func (this *NodeIPAddressDAO) FindNodeAccessIPAddresses(tx *dbs.Tx, nodeId int64) (result []*NodeIPAddress, err error) {
// FindNodeAccessIPAddresses 查找节点所有的可访问的IP地址
func (this *NodeIPAddressDAO) FindNodeAccessIPAddresses(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (result []*NodeIPAddress, err error) {
if len(role) == 0 {
role = nodeconfigs.NodeRoleNode
}
_, err = this.Query(tx).
Attr("nodeId", nodeId).
State(NodeIPAddressStateEnabled).

View File

@@ -1,9 +1,10 @@
package models
// 节点IP地址
// NodeIPAddress 节点IP地址
type NodeIPAddress struct {
Id uint32 `field:"id"` // ID
NodeId uint32 `field:"nodeId"` // 节点ID
Role string `field:"role"` // 节点角色
Name string `field:"name"` // 名称
Ip string `field:"ip"` // IP地址
Description string `field:"description"` // 描述
@@ -15,6 +16,7 @@ type NodeIPAddress struct {
type NodeIPAddressOperator struct {
Id interface{} // ID
NodeId interface{} // 节点ID
Role interface{} // 节点角色
Name interface{} // 名称
Ip interface{} // IP地址
Description interface{} // 描述

View File

@@ -3,6 +3,7 @@ package models
import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -35,7 +36,7 @@ func init() {
}
// CreateLog 创建日志
func (this *NodeLogDAO) CreateLog(tx *dbs.Tx, nodeRole NodeRole, nodeId int64, serverId int64, level string, tag string, description string, createdAt int64) error {
func (this *NodeLogDAO) CreateLog(tx *dbs.Tx, nodeRole nodeconfigs.NodeRole, nodeId int64, serverId int64, level string, tag string, description string, createdAt int64) error {
hash := stringutil.Md5(nodeRole + "@" + strconv.FormatInt(nodeId, 10) + "@" + strconv.FormatInt(serverId, 10) + "@" + level + "@" + tag + "@" + description)
// 检查是否在重复最后一条,避免重复创建
@@ -67,6 +68,7 @@ func (this *NodeLogDAO) CreateLog(tx *dbs.Tx, nodeRole NodeRole, nodeId int64, s
op.CreatedAt = createdAt
op.Day = timeutil.FormatTime("Ymd", createdAt)
op.Hash = hash
op.Count = 1
err = this.Save(tx, op)
return err
}
@@ -93,8 +95,10 @@ func (this *NodeLogDAO) CountNodeLogs(tx *dbs.Tx, role string, nodeId int64, ser
query.Attr("nodeId", nodeId)
} else {
switch role {
case NodeRoleNode:
case nodeconfigs.NodeRoleNode:
query.Where("nodeId IN (SELECT id FROM " + SharedNodeDAO.Table + " WHERE state=1)")
case nodeconfigs.NodeRoleDNS:
query.Where("nodeId IN (SELECT id FROM edgeNSNodes WHERE state=1)") // 没有用 SharedNSNodeDAO() 因为有包循环引用的问题
}
}
if serverId > 0 {
@@ -138,8 +142,10 @@ func (this *NodeLogDAO) ListNodeLogs(tx *dbs.Tx,
query.Attr("nodeId", nodeId)
} else {
switch role {
case NodeRoleNode:
case nodeconfigs.NodeRoleNode:
query.Where("nodeId IN (SELECT id FROM " + SharedNodeDAO.Table + " WHERE state=1)")
case nodeconfigs.NodeRoleDNS:
query.Where("nodeId IN (SELECT id FROM edgeNSNodes WHERE state=1)") // 没有用 SharedNSNodeDAO() 因为有包循环引用的问题
}
}
if serverId > 0 {

View File

@@ -1,17 +0,0 @@
package models
type NodeRole = string
const (
NodeRoleAdmin NodeRole = "admin"
NodeRoleUser NodeRole = "user"
NodeRoleProvider NodeRole = "provider"
NodeRoleAPI NodeRole = "api"
NodeRoleDatabase NodeRole = "database"
NodeRoleLog NodeRole = "log"
NodeRoleDNS NodeRole = "dns"
NodeRoleMonitor NodeRole = "monitor"
NodeRoleNode NodeRole = "node"
NodeRoleCluster NodeRole = "cluster"
NodeRoleAuthority NodeRole = "authority"
)

View File

@@ -13,8 +13,9 @@ import (
type NodeTaskType = string
const (
NodeTaskTypeConfigChanged NodeTaskType = "configChanged"
NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged"
NodeTaskTypeConfigChanged NodeTaskType = "configChanged"
NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged"
NodeTaskTypeNodeVersionChanged NodeTaskType = "nodeVersionChanged"
)
type NodeTaskDAO dbs.DAO

View File

@@ -33,7 +33,7 @@ func init() {
}
// CreateValue 创建值
func (this *NodeValueDAO) CreateValue(tx *dbs.Tx, role NodeRole, nodeId int64, item string, valueJSON []byte, createdAt int64) error {
func (this *NodeValueDAO) CreateValue(tx *dbs.Tx, role nodeconfigs.NodeRole, nodeId int64, item string, valueJSON []byte, createdAt int64) error {
day := timeutil.FormatTime("Ymd", createdAt)
hour := timeutil.FormatTime("YmdH", createdAt)
minute := timeutil.FormatTime("YmdHi", createdAt)

View File

@@ -1,6 +1,7 @@
package models
import (
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/maps"
@@ -13,7 +14,7 @@ func TestNodeValueDAO_CreateValue(t *testing.T) {
m := maps.Map{
"hello": "world12344",
}
err := dao.CreateValue(nil, NodeRoleNode, 1, "test", m.AsJSON(), time.Now().Unix())
err := dao.CreateValue(nil, nodeconfigs.NodeRoleNode, 1, "test", m.AsJSON(), time.Now().Unix())
if err != nil {
t.Fatal(err)
}

View File

@@ -5,6 +5,7 @@ const (
LevelInfo = "info"
LevelWarning = "warning"
LevelError = "error"
LevelSuccess = "success"
LogTypeAdmin = "admin"
LogTypeUser = "user"

View File

@@ -0,0 +1,315 @@
package models
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/configs"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/types"
timeutil "github.com/iwind/TeaGo/utils/time"
"regexp"
"sort"
"strconv"
"strings"
"sync"
"time"
)
type NSAccessLogDAO dbs.DAO
func NewNSAccessLogDAO() *NSAccessLogDAO {
return dbs.NewDAO(&NSAccessLogDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNSAccessLogs",
Model: new(NSAccessLog),
PkName: "id",
},
}).(*NSAccessLogDAO)
}
var SharedNSAccessLogDAO *NSAccessLogDAO
func init() {
dbs.OnReady(func() {
SharedNSAccessLogDAO = NewNSAccessLogDAO()
})
}
// CreateNSAccessLogs 创建访问日志
func (this *NSAccessLogDAO) CreateNSAccessLogs(tx *dbs.Tx, accessLogs []*pb.NSAccessLog) error {
dao := randomNSAccessLogDAO()
if dao == nil {
dao = &NSAccessLogDAOWrapper{
DAO: SharedNSAccessLogDAO,
NodeId: 0,
}
}
return this.CreateNSAccessLogsWithDAO(tx, dao, accessLogs)
}
// CreateNSAccessLogsWithDAO 使用特定的DAO创建访问日志
func (this *NSAccessLogDAO) CreateNSAccessLogsWithDAO(tx *dbs.Tx, daoWrapper *NSAccessLogDAOWrapper, accessLogs []*pb.NSAccessLog) error {
if daoWrapper == nil {
return errors.New("dao should not be nil")
}
if len(accessLogs) == 0 {
return nil
}
dao := daoWrapper.DAO
// TODO 改成事务批量提交,以加快速度
for _, accessLog := range accessLogs {
day := timeutil.Format("Ymd", time.Unix(accessLog.Timestamp, 0))
table, err := findNSAccessLogTable(dao.Instance, day, false)
if err != nil {
return err
}
fields := map[string]interface{}{}
fields["nodeId"] = accessLog.NsNodeId
fields["domainId"] = accessLog.NsDomainId
fields["recordId"] = accessLog.NsRecordId
fields["createdAt"] = accessLog.Timestamp
fields["requestId"] = accessLog.RequestId + strconv.FormatInt(time.Now().UnixNano(), 10) + configs.PaddingId
content, err := json.Marshal(accessLog)
if err != nil {
return err
}
fields["content"] = content
_, err = dao.Query(tx).
Table(table).
Sets(fields).
Insert()
if err != nil {
// 是否为 Error 1146: Table 'xxx.xxx' doesn't exist 如果是,则创建表之后重试
if strings.Contains(err.Error(), "1146") {
table, err = findNSAccessLogTable(dao.Instance, day, true)
if err != nil {
return err
}
_, err = dao.Query(tx).
Table(table).
Sets(fields).
Insert()
if err != nil {
return err
}
}
}
}
return nil
}
// ListAccessLogs 读取往前的 单页访问日志
func (this *NSAccessLogDAO) ListAccessLogs(tx *dbs.Tx, lastRequestId string, size int64, day string, nodeId int64, domainId int64, recordId int64, keyword string, reverse bool) (result []*NSAccessLog, nextLastRequestId string, hasMore bool, err error) {
if len(day) != 8 {
return
}
// 限制能查询的最大条数,防止占用内存过多
if size > 1000 {
size = 1000
}
result, nextLastRequestId, err = this.listAccessLogs(tx, lastRequestId, size, day, nodeId, domainId, recordId, keyword, reverse)
if err != nil || int64(len(result)) < size {
return
}
moreResult, _, _ := this.listAccessLogs(tx, nextLastRequestId, 1, day, nodeId, domainId, recordId, keyword, reverse)
hasMore = len(moreResult) > 0
return
}
// 读取往前的单页访问日志
func (this *NSAccessLogDAO) listAccessLogs(tx *dbs.Tx, lastRequestId string, size int64, day string, nodeId int64, domainId int64, recordId int64, keyword string, reverse bool) (result []*NSAccessLog, nextLastRequestId string, err error) {
if size <= 0 {
return nil, lastRequestId, nil
}
accessLogLocker.RLock()
daoList := []*NSAccessLogDAOWrapper{}
for _, daoWrapper := range nsAccessLogDAOMapping {
daoList = append(daoList, daoWrapper)
}
accessLogLocker.RUnlock()
if len(daoList) == 0 {
daoList = []*NSAccessLogDAOWrapper{{
DAO: SharedNSAccessLogDAO,
NodeId: 0,
}}
}
locker := sync.Mutex{}
count := len(daoList)
wg := &sync.WaitGroup{}
wg.Add(count)
for _, daoWrapper := range daoList {
go func(daoWrapper *NSAccessLogDAOWrapper) {
defer wg.Done()
dao := daoWrapper.DAO
tableName, exists, err := findNSAccessLogTableName(dao.Instance, day)
if !exists {
// 表格不存在则跳过
return
}
if err != nil {
logs.Println("[DB_NODE]" + err.Error())
return
}
query := dao.Query(tx)
// 条件
if nodeId > 0 {
query.Attr("nodeId", nodeId)
}
if domainId > 0 {
query.Attr("domainId", domainId)
}
if recordId > 0 {
query.Attr("recordId", recordId)
}
// offset
if len(lastRequestId) > 0 {
if !reverse {
query.Where("requestId<:requestId").
Param("requestId", lastRequestId)
} else {
query.Where("requestId>:requestId").
Param("requestId", lastRequestId)
}
}
// keyword
if len(keyword) > 0 {
query.Where("(JSON_EXTRACT(content, '$.remoteAddr') LIKE :keyword OR JSON_EXTRACT(content, '$.questionName') LIKE :keyword OR JSON_EXTRACT(content, '$.recordValue') LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
if !reverse {
query.Desc("requestId")
} else {
query.Asc("requestId")
}
// 开始查询
ones, err := query.
Table(tableName).
Limit(size).
FindAll()
if err != nil {
logs.Println("[DB_NODE]" + err.Error())
return
}
locker.Lock()
for _, one := range ones {
accessLog := one.(*NSAccessLog)
result = append(result, accessLog)
}
locker.Unlock()
}(daoWrapper)
}
wg.Wait()
if len(result) == 0 {
return nil, lastRequestId, nil
}
// 按照requestId排序
sort.Slice(result, func(i, j int) bool {
if !reverse {
return result[i].RequestId > result[j].RequestId
} else {
return result[i].RequestId < result[j].RequestId
}
})
if int64(len(result)) > size {
result = result[:size]
}
requestId := result[len(result)-1].RequestId
if reverse {
lists.Reverse(result)
}
if !reverse {
return result, requestId, nil
} else {
return result, requestId, nil
}
}
// FindAccessLogWithRequestId 根据请求ID获取访问日志
func (this *NSAccessLogDAO) FindAccessLogWithRequestId(tx *dbs.Tx, requestId string) (*NSAccessLog, error) {
if !regexp.MustCompile(`^\d{30,}`).MatchString(requestId) {
return nil, errors.New("invalid requestId")
}
accessLogLocker.RLock()
daoList := []*NSAccessLogDAOWrapper{}
for _, daoWrapper := range nsAccessLogDAOMapping {
daoList = append(daoList, daoWrapper)
}
accessLogLocker.RUnlock()
if len(daoList) == 0 {
daoList = []*NSAccessLogDAOWrapper{{
DAO: SharedNSAccessLogDAO,
NodeId: 0,
}}
}
count := len(daoList)
wg := &sync.WaitGroup{}
wg.Add(count)
var result *NSAccessLog = nil
day := timeutil.FormatTime("Ymd", types.Int64(requestId[:10]))
for _, daoWrapper := range daoList {
go func(daoWrapper *NSAccessLogDAOWrapper) {
defer wg.Done()
dao := daoWrapper.DAO
tableName, exists, err := findNSAccessLogTableName(dao.Instance, day)
if err != nil {
logs.Println("[DB_NODE]" + err.Error())
return
}
if !exists {
return
}
one, err := dao.Query(tx).
Table(tableName).
Attr("requestId", requestId).
Find()
if err != nil {
logs.Println("[DB_NODE]" + err.Error())
return
}
if one != nil {
result = one.(*NSAccessLog)
}
}(daoWrapper)
}
wg.Wait()
return result, nil
}

View File

@@ -0,0 +1,6 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,26 @@
package models
// NSAccessLog 域名服务访问日志
type NSAccessLog struct {
Id uint64 `field:"id"` // ID
NodeId uint32 `field:"nodeId"` // 节点ID
DomainId uint32 `field:"domainId"` // 域名ID
RecordId uint32 `field:"recordId"` // 记录ID
Content string `field:"content"` // 访问数据
RequestId string `field:"requestId"` // 请求ID
CreatedAt uint64 `field:"createdAt"` // 创建时间
}
type NSAccessLogOperator struct {
Id interface{} // ID
NodeId interface{} // 节点ID
DomainId interface{} // 域名ID
RecordId interface{} // 记录ID
Content interface{} // 访问数据
RequestId interface{} // 请求ID
CreatedAt interface{} // 创建时间
}
func NewNSAccessLogOperator() *NSAccessLogOperator {
return &NSAccessLogOperator{}
}

View File

@@ -0,0 +1,17 @@
package models
import (
"encoding/json"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// ToPB 转换成PB对象
func (this *NSAccessLog) ToPB() (*pb.NSAccessLog, error) {
p := &pb.NSAccessLog{}
err := json.Unmarshal([]byte(this.Content), p)
if err != nil {
return nil, err
}
p.RequestId = this.RequestId
return p, nil
}

View File

@@ -38,12 +38,12 @@ func init() {
})
}
// 初始化
// Init 初始化
func (this *ReverseProxyDAO) Init() {
_ = this.DAOObject.Init()
}
// 启用条目
// EnableReverseProxy 启用条目
func (this *ReverseProxyDAO) EnableReverseProxy(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -55,7 +55,7 @@ func (this *ReverseProxyDAO) EnableReverseProxy(tx *dbs.Tx, id int64) error {
return this.NotifyUpdate(tx, id)
}
// 禁用条目
// DisableReverseProxy 禁用条目
func (this *ReverseProxyDAO) DisableReverseProxy(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -67,7 +67,7 @@ func (this *ReverseProxyDAO) DisableReverseProxy(tx *dbs.Tx, id int64) error {
return this.NotifyUpdate(tx, id)
}
// 查找启用中的条目
// FindEnabledReverseProxy 查找启用中的条目
func (this *ReverseProxyDAO) FindEnabledReverseProxy(tx *dbs.Tx, id int64) (*ReverseProxy, error) {
result, err := this.Query(tx).
Pk(id).
@@ -79,7 +79,7 @@ func (this *ReverseProxyDAO) FindEnabledReverseProxy(tx *dbs.Tx, id int64) (*Rev
return result.(*ReverseProxy), err
}
// 根据iD组合配置
// ComposeReverseProxyConfig 根据ID组合配置
func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyId int64) (*serverconfigs.ReverseProxyConfig, error) {
reverseProxy, err := this.FindEnabledReverseProxy(tx, reverseProxyId)
if err != nil {
@@ -184,13 +184,14 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
return config, nil
}
// 创建反向代理
// CreateReverseProxy 创建反向代理
func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userId int64, schedulingJSON []byte, primaryOriginsJSON []byte, backupOriginsJSON []byte) (int64, error) {
op := NewReverseProxyOperator()
op.IsOn = true
op.State = ReverseProxyStateEnabled
op.AdminId = adminId
op.UserId = userId
op.RequestHostType = serverconfigs.RequestHostTypeProxyServer
defaultHeaders := []string{"X-Real-IP", "X-Forwarded-For", "X-Forwarded-By", "X-Forwarded-Host", "X-Forwarded-Proto"}
defaultHeadersJSON, err := json.Marshal(defaultHeaders)
@@ -216,7 +217,7 @@ func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userI
return types.Int64(op.Id), nil
}
// 修改反向代理调度算法
// UpdateReverseProxyScheduling 修改反向代理调度算法
func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reverseProxyId int64, schedulingJSON []byte) error {
if reverseProxyId <= 0 {
return errors.New("invalid reverseProxyId")
@@ -235,7 +236,7 @@ func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reversePro
return this.NotifyUpdate(tx, reverseProxyId)
}
// 修改主要源站
// UpdateReverseProxyPrimaryOrigins 修改主要源站
func (this *ReverseProxyDAO) UpdateReverseProxyPrimaryOrigins(tx *dbs.Tx, reverseProxyId int64, origins []byte) error {
if reverseProxyId <= 0 {
return errors.New("invalid reverseProxyId")
@@ -254,7 +255,7 @@ func (this *ReverseProxyDAO) UpdateReverseProxyPrimaryOrigins(tx *dbs.Tx, revers
return this.NotifyUpdate(tx, reverseProxyId)
}
// 修改备用源站
// UpdateReverseProxyBackupOrigins 修改备用源站
func (this *ReverseProxyDAO) UpdateReverseProxyBackupOrigins(tx *dbs.Tx, reverseProxyId int64, origins []byte) error {
if reverseProxyId <= 0 {
return errors.New("invalid reverseProxyId")
@@ -273,7 +274,7 @@ func (this *ReverseProxyDAO) UpdateReverseProxyBackupOrigins(tx *dbs.Tx, reverse
return this.NotifyUpdate(tx, reverseProxyId)
}
// 修改是否启用
// UpdateReverseProxy 修改是否启用
func (this *ReverseProxyDAO) UpdateReverseProxy(tx *dbs.Tx, reverseProxyId int64, requestHostType int8, requestHost string, requestURI string, stripPrefix string, autoFlush bool, addHeaders []string, connTimeout *shared.TimeDuration, readTimeout *shared.TimeDuration, idleTimeout *shared.TimeDuration, maxConns int32, maxIdleConns int32) error {
if reverseProxyId <= 0 {
return errors.New("invalid reverseProxyId")
@@ -340,7 +341,7 @@ func (this *ReverseProxyDAO) UpdateReverseProxy(tx *dbs.Tx, reverseProxyId int64
return this.NotifyUpdate(tx, reverseProxyId)
}
// 查找包含某个源站的反向代理ID
// FindReverseProxyContainsOriginId 查找包含某个源站的反向代理ID
func (this *ReverseProxyDAO) FindReverseProxyContainsOriginId(tx *dbs.Tx, originId int64) (int64, error) {
return this.Query(tx).
ResultPk().
@@ -351,7 +352,31 @@ func (this *ReverseProxyDAO) FindReverseProxyContainsOriginId(tx *dbs.Tx, origin
FindInt64Col(0)
}
// 通知更新
// CheckUserReverseProxy 检查用户权限
func (this *ReverseProxyDAO) CheckUserReverseProxy(tx *dbs.Tx, userId int64, reverseProxyId int64) error {
exists, err := this.Query(tx).
Pk(reverseProxyId).
Attr("userId", userId).
Exist()
if err != nil {
return err
}
if exists {
return nil
}
// 检查server是否为用户的
serverId, err := SharedServerDAO.FindEnabledServerIdWithReverseProxyId(tx, reverseProxyId)
if err != nil {
return err
}
if serverId == 0 {
return ErrNotFound
}
return SharedServerDAO.CheckUserServer(tx, userId, serverId)
}
// NotifyUpdate 通知更新
func (this *ReverseProxyDAO) NotifyUpdate(tx *dbs.Tx, reverseProxyId int64) error {
serverId, err := SharedServerDAO.FindEnabledServerIdWithReverseProxyId(tx, reverseProxyId)
if err != nil {

View File

@@ -7,6 +7,7 @@ import (
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
"regexp"
)
type ServerDailyStatDAO dbs.DAO
@@ -30,24 +31,33 @@ func init() {
})
}
// 提交数据
// SaveStats 提交数据
func (this *ServerDailyStatDAO) SaveStats(tx *dbs.Tx, stats []*pb.ServerDailyStat) error {
for _, stat := range stats {
day := timeutil.FormatTime("Ymd", stat.CreatedAt)
timeFrom := timeutil.FormatTime("His", stat.CreatedAt)
timeTo := timeutil.FormatTime("His", stat.CreatedAt+5*60) // 5分钟
timeTo := timeutil.FormatTime("His", stat.CreatedAt+5*60-1) // 5分钟
_, _, err := this.Query(tx).
Param("bytes", stat.Bytes).
Param("cachedBytes", stat.CachedBytes).
Param("countRequests", stat.CountRequests).
Param("countCachedRequests", stat.CountCachedRequests).
InsertOrUpdate(maps.Map{
"serverId": stat.ServerId,
"regionId": stat.RegionId,
"bytes": dbs.SQL("bytes+:bytes"),
"day": day,
"timeFrom": timeFrom,
"timeTo": timeTo,
"serverId": stat.ServerId,
"regionId": stat.RegionId,
"bytes": dbs.SQL("bytes+:bytes"),
"cachedBytes": dbs.SQL("cachedBytes+:cachedBytes"),
"countRequests": dbs.SQL("countRequests+:countRequests"),
"countCachedRequests": dbs.SQL("countCachedRequests+:countCachedRequests"),
"day": day,
"timeFrom": timeFrom,
"timeTo": timeTo,
}, maps.Map{
"bytes": dbs.SQL("bytes+:bytes"),
"bytes": dbs.SQL("bytes+:bytes"),
"cachedBytes": dbs.SQL("cachedBytes+:cachedBytes"),
"countRequests": dbs.SQL("countRequests+:countRequests"),
"countCachedRequests": dbs.SQL("countCachedRequests+:countCachedRequests"),
})
if err != nil {
return err
@@ -56,7 +66,7 @@ func (this *ServerDailyStatDAO) SaveStats(tx *dbs.Tx, stats []*pb.ServerDailySta
return nil
}
// 根据用户计算某月合计
// SumUserMonthly 根据用户计算某月合计
// month 格式为YYYYMM
func (this *ServerDailyStatDAO) SumUserMonthly(tx *dbs.Tx, userId int64, regionId int64, month string) (int64, error) {
query := this.Query(tx)
@@ -69,7 +79,7 @@ func (this *ServerDailyStatDAO) SumUserMonthly(tx *dbs.Tx, userId int64, regionI
SumInt64("bytes", 0)
}
// 获取某月带宽峰值
// SumUserMonthlyPeek 获取某月带宽峰值
// month 格式为YYYYMM
func (this *ServerDailyStatDAO) SumUserMonthlyPeek(tx *dbs.Tx, userId int64, regionId int64, month string) (int64, error) {
query := this.Query(tx)
@@ -86,7 +96,7 @@ func (this *ServerDailyStatDAO) SumUserMonthlyPeek(tx *dbs.Tx, userId int64, reg
return int64(max), nil
}
// 获取某天流量总和
// SumUserDaily 获取某天流量总和
// day 格式为YYYYMMDD
func (this *ServerDailyStatDAO) SumUserDaily(tx *dbs.Tx, userId int64, regionId int64, day string) (int64, error) {
query := this.Query(tx)
@@ -100,7 +110,7 @@ func (this *ServerDailyStatDAO) SumUserDaily(tx *dbs.Tx, userId int64, regionId
SumInt64("bytes", 0)
}
// 获取某天带宽峰值
// SumUserDailyPeek 获取某天带宽峰值
// day 格式为YYYYMMDD
func (this *ServerDailyStatDAO) SumUserDailyPeek(tx *dbs.Tx, userId int64, regionId int64, day string) (int64, error) {
query := this.Query(tx)
@@ -117,3 +127,93 @@ func (this *ServerDailyStatDAO) SumUserDailyPeek(tx *dbs.Tx, userId int64, regio
}
return int64(max), nil
}
// SumMinutelyStat 获取某个分钟内的流量
// minute 格式为YYYYMMDDHHMM并且已经格式化成每5分钟一个值
func (this *ServerDailyStatDAO) SumMinutelyStat(tx *dbs.Tx, serverId int64, minute string) (stat *pb.ServerDailyStat, err error) {
stat = &pb.ServerDailyStat{}
if !regexp.MustCompile(`^\d{12}$`).MatchString(minute) {
return
}
one, _, err := this.Query(tx).
Result("SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests").
Attr("serverId", serverId).
Attr("day", minute[:8]).
Attr("timeFrom", minute[8:]+"00").
FindOne()
if err != nil {
return nil, err
}
if one == nil {
return
}
stat.Bytes = one.GetInt64("bytes")
stat.CachedBytes = one.GetInt64("cachedBytes")
stat.CountRequests = one.GetInt64("countRequests")
stat.CountCachedRequests = one.GetInt64("countCachedRequests")
return
}
// SumHourlyStat 获取某个小时内的流量
// hour 格式为YYYYMMDDHH
func (this *ServerDailyStatDAO) SumHourlyStat(tx *dbs.Tx, serverId int64, hour string) (stat *pb.ServerDailyStat, err error) {
stat = &pb.ServerDailyStat{}
if !regexp.MustCompile(`^\d{10}$`).MatchString(hour) {
return
}
one, _, err := this.Query(tx).
Result("SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests").
Attr("serverId", serverId).
Attr("day", hour[:8]).
Gte("timeFrom", hour[8:]+"0000").
Lte("timeTo", hour[8:]+"5959").
FindOne()
if err != nil {
return nil, err
}
if one == nil {
return
}
stat.Bytes = one.GetInt64("bytes")
stat.CachedBytes = one.GetInt64("cachedBytes")
stat.CountRequests = one.GetInt64("countRequests")
stat.CountCachedRequests = one.GetInt64("countCachedRequests")
return
}
// SumDailyStat 获取某天内的流量
// day 格式为YYYYMMDD
func (this *ServerDailyStatDAO) SumDailyStat(tx *dbs.Tx, serverId int64, day string) (stat *pb.ServerDailyStat, err error) {
stat = &pb.ServerDailyStat{}
if !regexp.MustCompile(`^\d{8}$`).MatchString(day) {
return
}
one, _, err := this.Query(tx).
Result("SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests").
Attr("serverId", serverId).
Attr("day", day).
FindOne()
if err != nil {
return nil, err
}
if one == nil {
return
}
stat.Bytes = one.GetInt64("bytes")
stat.CachedBytes = one.GetInt64("cachedBytes")
stat.CountRequests = one.GetInt64("countRequests")
stat.CountCachedRequests = one.GetInt64("countCachedRequests")
return
}

View File

@@ -4,6 +4,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs"
timeutil "github.com/iwind/TeaGo/utils/time"
"testing"
)
@@ -51,3 +52,25 @@ func TestServerDailyStatDAO_SumUserMonthly(t *testing.T) {
}
t.Log("bytes:", bytes)
}
func TestServerDailyStatDAO_SumHourlyRequests(t *testing.T) {
dbs.NotifyReady()
var tx *dbs.Tx
stat, err := NewServerDailyStatDAO().SumHourlyStat(tx, 23, timeutil.Format("YmdH"))
if err != nil {
t.Fatal(err)
}
logs.PrintAsJSON(stat, t)
}
func TestServerDailyStatDAO_SumMinutelyRequests(t *testing.T) {
dbs.NotifyReady()
var tx *dbs.Tx
stat, err := NewServerDailyStatDAO().SumMinutelyStat(tx, 23, timeutil.Format("Ymd") + "1435")
if err != nil {
t.Fatal(err)
}
logs.PrintAsJSON(stat, t)
}

View File

@@ -1,26 +1,32 @@
package models
// 计费流量统计
// ServerDailyStat 计费流量统计
type ServerDailyStat struct {
Id uint64 `field:"id"` // ID
ServerId uint32 `field:"serverId"` // 服务ID
RegionId uint32 `field:"regionId"` // 区域ID
Bytes uint64 `field:"bytes"` // 流量
Day string `field:"day"` // 日期YYYYMMDD
TimeFrom string `field:"timeFrom"` // 开始时间HHMMSS
TimeTo string `field:"timeTo"` // 结束时间
IsCharged uint8 `field:"isCharged"` // 是否已计算费用
Id uint64 `field:"id"` // ID
ServerId uint32 `field:"serverId"` // 服务ID
RegionId uint32 `field:"regionId"` // 区域ID
Bytes uint64 `field:"bytes"` // 流量
CachedBytes uint64 `field:"cachedBytes"` // 缓存的流量
CountRequests uint64 `field:"countRequests"` // 请求数
CountCachedRequests uint64 `field:"countCachedRequests"` // 缓存的请求数
Day string `field:"day"` // 日期YYYYMMDD
TimeFrom string `field:"timeFrom"` // 开始时间HHMMSS
TimeTo string `field:"timeTo"` // 结束时间
IsCharged uint8 `field:"isCharged"` // 是否已计算费用
}
type ServerDailyStatOperator struct {
Id interface{} // ID
ServerId interface{} // 服务ID
RegionId interface{} // 区域ID
Bytes interface{} // 流量
Day interface{} // 日期YYYYMMDD
TimeFrom interface{} // 开始时间HHMMSS
TimeTo interface{} // 结束时间
IsCharged interface{} // 是否已计算费用
Id interface{} // ID
ServerId interface{} // 服务ID
RegionId interface{} // 区域ID
Bytes interface{} // 流量
CachedBytes interface{} // 缓存的流量
CountRequests interface{} // 请求数
CountCachedRequests interface{} // 缓存的请求数
Day interface{} // 日期YYYYMMDD
TimeFrom interface{} // 开始时间HHMMSS
TimeTo interface{} // 结束时间
IsCharged interface{} // 是否已计算费用
}
func NewServerDailyStatOperator() *ServerDailyStatOperator {

View File

@@ -1205,19 +1205,10 @@ func (this *ServerDAO) CheckUserServer(tx *dbs.Tx, userId int64, serverId int64)
}
// UpdateUserServersClusterId 设置一个用户下的所有服务的所属集群
func (this *ServerDAO) UpdateUserServersClusterId(tx *dbs.Tx, userId int64, clusterId int64) error {
// 之前的cluster
oldClusterId, err := SharedUserDAO.FindUserClusterId(tx, userId)
if err != nil {
return err
}
if oldClusterId == clusterId {
return nil
}
_, err = this.Query(tx).
func (this *ServerDAO) UpdateUserServersClusterId(tx *dbs.Tx, userId int64, oldClusterId, newClusterId int64) error {
_, err := this.Query(tx).
Attr("userId", userId).
Set("clusterId", clusterId).
Set("clusterId", newClusterId).
Update()
if err != nil {
return err
@@ -1232,14 +1223,22 @@ func (this *ServerDAO) UpdateUserServersClusterId(tx *dbs.Tx, userId int64, clus
if err != nil {
return err
}
}
if clusterId > 0 {
err = SharedNodeTaskDAO.CreateClusterTask(tx, clusterId, NodeTaskTypeConfigChanged)
err = dns.SharedDNSTaskDAO.CreateClusterTask(tx, oldClusterId, dns.DNSTaskTypeClusterChange)
if err != nil {
return err
}
err = SharedNodeTaskDAO.CreateClusterTask(tx, clusterId, NodeTaskTypeIPItemChanged)
}
if newClusterId > 0 {
err = SharedNodeTaskDAO.CreateClusterTask(tx, newClusterId, NodeTaskTypeConfigChanged)
if err != nil {
return err
}
err = SharedNodeTaskDAO.CreateClusterTask(tx, newClusterId, NodeTaskTypeIPItemChanged)
if err != nil {
return err
}
err = dns.SharedDNSTaskDAO.CreateClusterTask(tx, newClusterId, dns.DNSTaskTypeClusterChange)
if err != nil {
return err
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/rands"
"time"
)
const (
@@ -34,7 +35,7 @@ func init() {
})
}
// 启用条目
// EnableUserAccessKey 启用条目
func (this *UserAccessKeyDAO) EnableUserAccessKey(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -43,7 +44,7 @@ func (this *UserAccessKeyDAO) EnableUserAccessKey(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableUserAccessKey 禁用条目
func (this *UserAccessKeyDAO) DisableUserAccessKey(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -52,7 +53,7 @@ func (this *UserAccessKeyDAO) DisableUserAccessKey(tx *dbs.Tx, id int64) error {
return err
}
// 查找启用中的条目
// FindEnabledUserAccessKey 查找启用中的条目
func (this *UserAccessKeyDAO) FindEnabledUserAccessKey(tx *dbs.Tx, id int64) (*UserAccessKey, error) {
result, err := this.Query(tx).
Pk(id).
@@ -64,12 +65,13 @@ func (this *UserAccessKeyDAO) FindEnabledUserAccessKey(tx *dbs.Tx, id int64) (*U
return result.(*UserAccessKey), err
}
// 创建Key
func (this *UserAccessKeyDAO) CreateAccessKey(tx *dbs.Tx, userId int64, description string) (int64, error) {
if userId <= 0 {
return 0, errors.New("invalid userId")
// CreateAccessKey 创建Key
func (this *UserAccessKeyDAO) CreateAccessKey(tx *dbs.Tx, adminId int64, userId int64, description string) (int64, error) {
if adminId <= 0 && userId <= 0 {
return 0, errors.New("invalid adminId or userId")
}
op := NewUserAccessKeyOperator()
op.AdminId = adminId
op.UserId = userId
op.Description = description
op.UniqueId = rands.String(16)
@@ -79,9 +81,11 @@ func (this *UserAccessKeyDAO) CreateAccessKey(tx *dbs.Tx, userId int64, descript
return this.SaveInt64(tx, op)
}
// 查找用户所有的Key
func (this *UserAccessKeyDAO) FindAllEnabledAccessKeys(tx *dbs.Tx, userId int64) (result []*UserAccessKey, err error) {
// FindAllEnabledAccessKeys 查找用户所有的Key
func (this *UserAccessKeyDAO) FindAllEnabledAccessKeys(tx *dbs.Tx, adminId int64, userId int64) (result []*UserAccessKey, err error) {
_, err = this.Query(tx).
Attr("adminId", adminId).
Attr("userId", userId).
State(UserAccessKeyStateEnabled).
DescPk().
Slice(&result).
@@ -89,16 +93,17 @@ func (this *UserAccessKeyDAO) FindAllEnabledAccessKeys(tx *dbs.Tx, userId int64)
return
}
// 检查用户的AccessKey
func (this *UserAccessKeyDAO) CheckUserAccessKey(tx *dbs.Tx, userId int64, accessKeyId int64) (bool, error) {
// CheckUserAccessKey 检查用户的AccessKey
func (this *UserAccessKeyDAO) CheckUserAccessKey(tx *dbs.Tx, adminId int64, userId int64, accessKeyId int64) (bool, error) {
return this.Query(tx).
Pk(accessKeyId).
State(UserAccessKeyStateEnabled).
Attr("adminId", adminId).
Attr("userId", userId).
Exist()
}
// 设置是否启用
// UpdateAccessKeyIsOn 设置是否启用
func (this *UserAccessKeyDAO) UpdateAccessKeyIsOn(tx *dbs.Tx, accessKeyId int64, isOn bool) error {
if accessKeyId <= 0 {
return errors.New("invalid accessKeyId")
@@ -110,7 +115,7 @@ func (this *UserAccessKeyDAO) UpdateAccessKeyIsOn(tx *dbs.Tx, accessKeyId int64,
return err
}
// 根据UniqueId查找AccessKey
// FindAccessKeyWithUniqueId 根据UniqueId查找AccessKey
func (this *UserAccessKeyDAO) FindAccessKeyWithUniqueId(tx *dbs.Tx, uniqueId string) (*UserAccessKey, error) {
one, err := this.Query(tx).
Attr("uniqueId", uniqueId).
@@ -123,3 +128,20 @@ func (this *UserAccessKeyDAO) FindAccessKeyWithUniqueId(tx *dbs.Tx, uniqueId str
return one.(*UserAccessKey), nil
}
// UpdateAccessKeyAccessedAt 更新AccessKey访问时间
func (this *UserAccessKeyDAO) UpdateAccessKeyAccessedAt(tx *dbs.Tx, accessKeyId int64) error {
return this.Query(tx).
Pk(accessKeyId).
Set("accessedAt", time.Now().Unix()).
UpdateQuickly()
}
// CountAllEnabledAccessKeys 计算可用AccessKey数量
func (this *UserAccessKeyDAO) CountAllEnabledAccessKeys(tx *dbs.Tx, adminId int64, userId int64) (int64, error) {
return this.Query(tx).
Attr("adminId", adminId).
Attr("userId", userId).
State(UserAccessKeyStateEnabled).
Count()
}

View File

@@ -1,25 +1,29 @@
package models
// AccessKey
// UserAccessKey AccessKey
type UserAccessKey struct {
Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
UserId uint32 `field:"userId"` // 用户ID
SubUserId uint32 `field:"subUserId"` // 子用户ID
IsOn uint8 `field:"isOn"` // 是否启用
UniqueId string `field:"uniqueId"` // 唯一的Key
Secret string `field:"secret"` // 密钥
Description string `field:"description"` // 备注
AccessedAt uint64 `field:"accessedAt"` // 最近一次访问时间
State uint8 `field:"state"` // 状态
}
type UserAccessKeyOperator struct {
Id interface{} // ID
AdminId interface{} // 管理员ID
UserId interface{} // 用户ID
SubUserId interface{} // 子用户ID
IsOn interface{} // 是否启用
UniqueId interface{} // 唯一的Key
Secret interface{} // 密钥
Description interface{} // 备注
AccessedAt interface{} // 最近一次访问时间
State interface{} // 状态
}

View File

@@ -36,7 +36,7 @@ func init() {
})
}
// 启用条目
// EnableUser 启用条目
func (this *UserDAO) EnableUser(tx *dbs.Tx, id int64) (rowsAffected int64, err error) {
return this.Query(tx).
Pk(id).
@@ -44,7 +44,7 @@ func (this *UserDAO) EnableUser(tx *dbs.Tx, id int64) (rowsAffected int64, err e
Update()
}
// 禁用条目
// DisableUser 禁用条目
func (this *UserDAO) DisableUser(tx *dbs.Tx, id int64) (rowsAffected int64, err error) {
return this.Query(tx).
Pk(id).
@@ -52,7 +52,7 @@ func (this *UserDAO) DisableUser(tx *dbs.Tx, id int64) (rowsAffected int64, err
Update()
}
// 查找启用中的条目
// FindEnabledUser 查找启用中的条目
func (this *UserDAO) FindEnabledUser(tx *dbs.Tx, id int64) (*User, error) {
result, err := this.Query(tx).
Pk(id).
@@ -64,7 +64,7 @@ func (this *UserDAO) FindEnabledUser(tx *dbs.Tx, id int64) (*User, error) {
return result.(*User), err
}
// 查找用户基本信息
// FindEnabledBasicUser 查找用户基本信息
func (this *UserDAO) FindEnabledBasicUser(tx *dbs.Tx, id int64) (*User, error) {
result, err := this.Query(tx).
Pk(id).
@@ -77,7 +77,7 @@ func (this *UserDAO) FindEnabledBasicUser(tx *dbs.Tx, id int64) (*User, error) {
return result.(*User), err
}
// 获取管理员名称
// FindUserFullname 获取管理员名称
func (this *UserDAO) FindUserFullname(tx *dbs.Tx, userId int64) (string, error) {
return this.Query(tx).
Pk(userId).
@@ -85,7 +85,7 @@ func (this *UserDAO) FindUserFullname(tx *dbs.Tx, userId int64) (string, error)
FindStringCol("")
}
// 创建用户
// CreateUser 创建用户
func (this *UserDAO) CreateUser(tx *dbs.Tx, username string, password string, fullname string, mobile string, tel string, email string, remark string, source string, clusterId int64) (int64, error) {
op := NewUserOperator()
op.Username = username
@@ -107,8 +107,8 @@ func (this *UserDAO) CreateUser(tx *dbs.Tx, username string, password string, fu
return types.Int64(op.Id), nil
}
// 修改用户
func (this *UserDAO) UpdateUser(tx *dbs.Tx, userId int64, username string, password string, fullname string, mobile string, tel string, email string, remark string, isOn bool, clusterId int64) error {
// UpdateUser 修改用户
func (this *UserDAO) UpdateUser(tx *dbs.Tx, userId int64, username string, password string, fullname string, mobile string, tel string, email string, remark string, isOn bool, nodeClusterId int64) error {
if userId <= 0 {
return errors.New("invalid userId")
}
@@ -123,13 +123,13 @@ func (this *UserDAO) UpdateUser(tx *dbs.Tx, userId int64, username string, passw
op.Tel = tel
op.Email = email
op.Remark = remark
op.ClusterId = nodeClusterId
op.IsOn = isOn
op.ClusterId = clusterId
err := this.Save(tx, op)
return err
}
// 修改用户基本信息
// UpdateUserInfo 修改用户基本信息
func (this *UserDAO) UpdateUserInfo(tx *dbs.Tx, userId int64, fullname string) error {
if userId <= 0 {
return errors.New("invalid userId")
@@ -140,7 +140,7 @@ func (this *UserDAO) UpdateUserInfo(tx *dbs.Tx, userId int64, fullname string) e
return this.Save(tx, op)
}
// 修改用户登录信息
// UpdateUserLogin 修改用户登录信息
func (this *UserDAO) UpdateUserLogin(tx *dbs.Tx, userId int64, username string, password string) error {
if userId <= 0 {
return errors.New("invalid userId")
@@ -155,7 +155,7 @@ func (this *UserDAO) UpdateUserLogin(tx *dbs.Tx, userId int64, username string,
return err
}
// 计算用户数量
// CountAllEnabledUsers 计算用户数量
func (this *UserDAO) CountAllEnabledUsers(tx *dbs.Tx, keyword string) (int64, error) {
query := this.Query(tx)
query.State(UserStateEnabled)
@@ -166,8 +166,8 @@ func (this *UserDAO) CountAllEnabledUsers(tx *dbs.Tx, keyword string) (int64, er
return query.Count()
}
// 列出单页用户
func (this *UserDAO) ListEnabledUsers(tx *dbs.Tx, keyword string) (result []*User, err error) {
// ListEnabledUsers 列出单页用户
func (this *UserDAO) ListEnabledUsers(tx *dbs.Tx, keyword string, offset int64, size int64) (result []*User, err error) {
query := this.Query(tx)
query.State(UserStateEnabled)
if len(keyword) > 0 {
@@ -176,12 +176,14 @@ func (this *UserDAO) ListEnabledUsers(tx *dbs.Tx, keyword string) (result []*Use
}
_, err = query.
DescPk().
Offset(offset).
Limit(size).
Slice(&result).
FindAll()
return
}
// 检查用户名是否存在
// ExistUser 检查用户名是否存在
func (this *UserDAO) ExistUser(tx *dbs.Tx, userId int64, username string) (bool, error) {
return this.Query(tx).
State(UserStateEnabled).
@@ -190,7 +192,7 @@ func (this *UserDAO) ExistUser(tx *dbs.Tx, userId int64, username string) (bool,
Exist()
}
// 列出单页的用户ID
// ListEnabledUserIds 列出单页的用户ID
func (this *UserDAO) ListEnabledUserIds(tx *dbs.Tx, offset, size int64) ([]int64, error) {
ones, _, err := this.Query(tx).
ResultPk().
@@ -209,7 +211,7 @@ func (this *UserDAO) ListEnabledUserIds(tx *dbs.Tx, offset, size int64) ([]int64
return result, nil
}
// 检查用户名、密码
// CheckUserPassword 检查用户名、密码
func (this *UserDAO) CheckUserPassword(tx *dbs.Tx, username string, encryptedPassword string) (int64, error) {
if len(username) == 0 || len(encryptedPassword) == 0 {
return 0, nil
@@ -223,7 +225,7 @@ func (this *UserDAO) CheckUserPassword(tx *dbs.Tx, username string, encryptedPas
FindInt64Col(0)
}
// 查找用户所在集群
// FindUserClusterId 查找用户所在集群
func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error) {
return this.Query(tx).
Pk(userId).
@@ -231,7 +233,7 @@ func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error)
FindInt64Col(0)
}
// 更新用户Features
// UpdateUserFeatures 更新用户Features
func (this *UserDAO) UpdateUserFeatures(tx *dbs.Tx, userId int64, featuresJSON []byte) error {
if userId <= 0 {
return errors.New("invalid userId")
@@ -249,7 +251,7 @@ func (this *UserDAO) UpdateUserFeatures(tx *dbs.Tx, userId int64, featuresJSON [
return nil
}
// 查找用户Features
// FindUserFeatures 查找用户Features
func (this *UserDAO) FindUserFeatures(tx *dbs.Tx, userId int64) ([]*UserFeature, error) {
featuresJSON, err := this.Query(tx).
Pk(userId).

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -142,7 +143,7 @@ func (this *UserNodeDAO) CreateUserNode(tx *dbs.Tx, name string, description str
return 0, err
}
secret := rands.String(32)
err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, NodeRoleUser)
err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleUser)
if err != nil {
return
}

View File

@@ -1,10 +1,11 @@
package dnsclients
package dnstypes
type RecordType = string
const (
RecordTypeA RecordType = "A"
RecordTypeCName RecordType = "CNAME"
RecordTypeAAAA RecordType = "AAAA"
RecordTypeCNAME RecordType = "CNAME"
RecordTypeTXT RecordType = "TXT"
)

View File

@@ -1,4 +1,4 @@
package dnsclients
package dnstypes
// Route 线路描述
type Route struct {

View File

@@ -2,6 +2,7 @@ package dnsclients
import (
"errors"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
@@ -31,7 +32,7 @@ func (this *AliDNSProvider) Auth(params maps.Map) error {
}
// GetRecords 获取域名列表
func (this *AliDNSProvider) GetRecords(domain string) (records []*Record, err error) {
func (this *AliDNSProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
pageNumber := 1
size := 100
@@ -48,11 +49,11 @@ func (this *AliDNSProvider) GetRecords(domain string) (records []*Record, err er
}
for _, record := range resp.DomainRecords.Record {
// 修正Record
if record.Type == RecordTypeCName && !strings.HasSuffix(record.Value, ".") {
if record.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(record.Value, ".") {
record.Value += "."
}
records = append(records, &Record{
records = append(records, &dnstypes.Record{
Id: record.RecordId,
Name: record.RR,
Type: record.Type,
@@ -71,7 +72,7 @@ func (this *AliDNSProvider) GetRecords(domain string) (records []*Record, err er
}
// GetRoutes 读取域名支持的线路数据
func (this *AliDNSProvider) GetRoutes(domain string) (routes []*Route, err error) {
func (this *AliDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
req := alidns.CreateDescribeSupportLinesRequest()
req.DomainName = domain
@@ -81,7 +82,7 @@ func (this *AliDNSProvider) GetRoutes(domain string) (routes []*Route, err error
return nil, err
}
for _, line := range resp.RecordLines.RecordLine {
routes = append(routes, &Route{
routes = append(routes, &dnstypes.Route{
Name: line.LineName,
Code: line.LineCode,
})
@@ -90,7 +91,7 @@ func (this *AliDNSProvider) GetRoutes(domain string) (routes []*Route, err error
}
// QueryRecord 查询单个记录
func (this *AliDNSProvider) QueryRecord(domain string, name string, recordType RecordType) (*Record, error) {
func (this *AliDNSProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
records, err := this.GetRecords(domain)
if err != nil {
return nil, err
@@ -104,7 +105,7 @@ func (this *AliDNSProvider) QueryRecord(domain string, name string, recordType R
}
// AddRecord 设置记录
func (this *AliDNSProvider) AddRecord(domain string, newRecord *Record) error {
func (this *AliDNSProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
req := alidns.CreateAddDomainRecordRequest()
req.RR = newRecord.Name
req.Type = newRecord.Type
@@ -125,7 +126,7 @@ func (this *AliDNSProvider) AddRecord(domain string, newRecord *Record) error {
}
// UpdateRecord 修改记录
func (this *AliDNSProvider) UpdateRecord(domain string, record *Record, newRecord *Record) error {
func (this *AliDNSProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
req := alidns.CreateUpdateDomainRecordRequest()
req.RecordId = record.Id
req.RR = newRecord.Name
@@ -139,7 +140,7 @@ func (this *AliDNSProvider) UpdateRecord(domain string, record *Record, newRecor
}
// DeleteRecord 删除记录
func (this *AliDNSProvider) DeleteRecord(domain string, record *Record) error {
func (this *AliDNSProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
req := alidns.CreateDeleteDomainRecordRequest()
req.RecordId = record.Id

View File

@@ -2,6 +2,7 @@ package dnsclients
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/dbs"
@@ -29,7 +30,7 @@ func TestAliDNSProvider_DeleteRecord(t *testing.T) {
t.Fatal(err)
}
err = provider.DeleteRecord("meloy.cn", &Record{
err = provider.DeleteRecord("meloy.cn", &dnstypes.Record{
Id: "20746603318032384",
})
if err != nil {
@@ -57,10 +58,10 @@ func TestAliDNSProvider_AddRecord(t *testing.T) {
t.Fatal(err)
}
err = provider.AddRecord("meloy.cn", &Record{
err = provider.AddRecord("meloy.cn", &dnstypes.Record{
Id: "",
Name: "test",
Type: RecordTypeA,
Type: dnstypes.RecordTypeA,
Value: "192.168.1.100",
Route: "unicom",
})
@@ -76,10 +77,10 @@ func TestAliDNSProvider_UpdateRecord(t *testing.T) {
t.Fatal(err)
}
err = provider.UpdateRecord("meloy.cn", &Record{Id: "20746664455255040"}, &Record{
err = provider.UpdateRecord("meloy.cn", &dnstypes.Record{Id: "20746664455255040"}, &dnstypes.Record{
Id: "",
Name: "test",
Type: RecordTypeA,
Type: dnstypes.RecordTypeA,
Value: "192.168.1.101",
Route: "unicom",
})

View File

@@ -7,6 +7,7 @@ import (
"crypto/tls"
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/cloudflare"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/iwind/TeaGo/maps"
"io"
@@ -59,7 +60,7 @@ func (this *CloudFlareProvider) Auth(params maps.Map) error {
}
// GetRecords 获取域名解析记录列表
func (this *CloudFlareProvider) GetRecords(domain string) (records []*Record, err error) {
func (this *CloudFlareProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
zoneId, err := this.findZoneIdWithDomain(domain)
if err != nil {
return nil, err
@@ -81,13 +82,13 @@ func (this *CloudFlareProvider) GetRecords(domain string) (records []*Record, er
for _, record := range resp.Result {
// 修正Record
if record.Type == RecordTypeCName && !strings.HasSuffix(record.Content, ".") {
if record.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(record.Content, ".") {
record.Content += "."
}
record.Name = strings.TrimSuffix(record.Name, "."+domain)
records = append(records, &Record{
records = append(records, &dnstypes.Record{
Id: record.Id,
Name: record.Name,
Type: record.Type,
@@ -101,15 +102,15 @@ func (this *CloudFlareProvider) GetRecords(domain string) (records []*Record, er
}
// GetRoutes 读取域名支持的线路数据
func (this *CloudFlareProvider) GetRoutes(domain string) (routes []*Route, err error) {
routes = []*Route{
func (this *CloudFlareProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
routes = []*dnstypes.Route{
{Name: "默认", Code: CloudFlareDefaultRoute},
}
return
}
// QueryRecord 查询单个记录
func (this *CloudFlareProvider) QueryRecord(domain string, name string, recordType RecordType) (*Record, error) {
func (this *CloudFlareProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
zoneId, err := this.findZoneIdWithDomain(domain)
if err != nil {
return nil, err
@@ -131,13 +132,13 @@ func (this *CloudFlareProvider) QueryRecord(domain string, name string, recordTy
record := resp.Result[0]
// 修正Record
if record.Type == RecordTypeCName && !strings.HasSuffix(record.Content, ".") {
if record.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(record.Content, ".") {
record.Content += "."
}
record.Name = strings.TrimSuffix(record.Name, "."+domain)
return &Record{
return &dnstypes.Record{
Id: record.Id,
Name: record.Name,
Type: record.Type,
@@ -147,7 +148,7 @@ func (this *CloudFlareProvider) QueryRecord(domain string, name string, recordTy
}
// AddRecord 设置记录
func (this *CloudFlareProvider) AddRecord(domain string, newRecord *Record) error {
func (this *CloudFlareProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
zoneId, err := this.findZoneIdWithDomain(domain)
if err != nil {
return err
@@ -167,7 +168,7 @@ func (this *CloudFlareProvider) AddRecord(domain string, newRecord *Record) erro
}
// UpdateRecord 修改记录
func (this *CloudFlareProvider) UpdateRecord(domain string, record *Record, newRecord *Record) error {
func (this *CloudFlareProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
zoneId, err := this.findZoneIdWithDomain(domain)
if err != nil {
return err
@@ -183,7 +184,7 @@ func (this *CloudFlareProvider) UpdateRecord(domain string, record *Record, newR
}
// DeleteRecord 删除记录
func (this *CloudFlareProvider) DeleteRecord(domain string, record *Record) error {
func (this *CloudFlareProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
zoneId, err := this.findZoneIdWithDomain(domain)
if err != nil {
return err

View File

@@ -4,6 +4,7 @@ package dnsclients
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs"
@@ -45,7 +46,7 @@ func TestCloudFlareProvider_QueryRecord(t *testing.T) {
}
{
t.Log("== www.meloy.cn/A ==")
record, err := provider.QueryRecord("meloy.cn", "www", RecordTypeA)
record, err := provider.QueryRecord("meloy.cn", "www", dnstypes.RecordTypeA)
if err != nil {
t.Fatal(err)
}
@@ -53,7 +54,7 @@ func TestCloudFlareProvider_QueryRecord(t *testing.T) {
}
{
t.Log("== www.meloy.cn/CNAME ==")
record, err := provider.QueryRecord("meloy.cn", "www", RecordTypeCName)
record, err := provider.QueryRecord("meloy.cn", "www", dnstypes.RecordTypeCNAME)
if err != nil {
t.Fatal(err)
}
@@ -61,7 +62,7 @@ func TestCloudFlareProvider_QueryRecord(t *testing.T) {
}
{
t.Log("== hello.meloy.cn ==")
record, err := provider.QueryRecord("meloy.cn", "hello", RecordTypeA)
record, err := provider.QueryRecord("meloy.cn", "hello", dnstypes.RecordTypeA)
if err != nil {
t.Fatal(err)
}
@@ -69,7 +70,7 @@ func TestCloudFlareProvider_QueryRecord(t *testing.T) {
}
{
t.Log("== test.meloy.cn ==")
record, err := provider.QueryRecord("meloy.cn", "test", RecordTypeCName)
record, err := provider.QueryRecord("meloy.cn", "test", dnstypes.RecordTypeCNAME)
if err != nil {
t.Fatal(err)
}
@@ -83,10 +84,10 @@ func TestCloudFlareProvider_AddRecord(t *testing.T) {
t.Fatal(err)
}
{
err = provider.AddRecord("meloy.cn", &Record{
err = provider.AddRecord("meloy.cn", &dnstypes.Record{
Id: "",
Name: "test",
Type: RecordTypeA,
Type: dnstypes.RecordTypeA,
Value: "182.92.212.46",
Route: "",
})
@@ -95,10 +96,10 @@ func TestCloudFlareProvider_AddRecord(t *testing.T) {
}
}
{
err = provider.AddRecord("meloy.cn", &Record{
err = provider.AddRecord("meloy.cn", &dnstypes.Record{
Id: "",
Name: "test1",
Type: RecordTypeCName,
Type: dnstypes.RecordTypeCNAME,
Value: "cdn.meloy.cn.",
Route: "",
})
@@ -114,10 +115,10 @@ func TestCloudFlareProvider_UpdateRecord(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = provider.UpdateRecord("meloy.cn", &Record{Id: "b4da7ad9f90173ec37c80ba6bb70641a"}, &Record{
err = provider.UpdateRecord("meloy.cn", &dnstypes.Record{Id: "b4da7ad9f90173ec37c80ba6bb70641a"}, &dnstypes.Record{
Id: "",
Name: "test1",
Type: RecordTypeCName,
Type: dnstypes.RecordTypeCNAME,
Value: "cdn123.meloy.cn.",
Route: "",
})
@@ -132,7 +133,7 @@ func TestCloudFlareProvider_DeleteRecord(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = provider.DeleteRecord("meloy.cn", &Record{
err = provider.DeleteRecord("meloy.cn", &dnstypes.Record{
Id: "86282d89bbd1f66a69ca409da84f34b1",
})
if err != nil {

View File

@@ -7,6 +7,7 @@ import (
"encoding/json"
"fmt"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/iwind/TeaGo/maps"
"io/ioutil"
@@ -49,7 +50,7 @@ func (this *CustomHTTPProvider) Auth(params maps.Map) error {
}
// GetRecords 获取域名解析记录列表
func (this *CustomHTTPProvider) GetRecords(domain string) (records []*Record, err error) {
func (this *CustomHTTPProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
resp, err := this.post(maps.Map{
"action": "GetRecords",
"domain": domain,
@@ -62,7 +63,7 @@ func (this *CustomHTTPProvider) GetRecords(domain string) (records []*Record, er
}
// GetRoutes 读取域名支持的线路数据
func (this *CustomHTTPProvider) GetRoutes(domain string) (routes []*Route, err error) {
func (this *CustomHTTPProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
resp, err := this.post(maps.Map{
"action": "GetRoutes",
"domain": domain,
@@ -75,7 +76,7 @@ func (this *CustomHTTPProvider) GetRoutes(domain string) (routes []*Route, err e
}
// QueryRecord 查询单个记录
func (this *CustomHTTPProvider) QueryRecord(domain string, name string, recordType RecordType) (*Record, error) {
func (this *CustomHTTPProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
resp, err := this.post(maps.Map{
"action": "QueryRecord",
"domain": domain,
@@ -88,7 +89,7 @@ func (this *CustomHTTPProvider) QueryRecord(domain string, name string, recordTy
if len(resp) == 0 {
return nil, nil
}
record := &Record{}
record := &dnstypes.Record{}
err = json.Unmarshal(resp, record)
if err != nil {
return nil, err
@@ -100,7 +101,7 @@ func (this *CustomHTTPProvider) QueryRecord(domain string, name string, recordTy
}
// AddRecord 设置记录
func (this *CustomHTTPProvider) AddRecord(domain string, newRecord *Record) error {
func (this *CustomHTTPProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
_, err := this.post(maps.Map{
"action": "AddRecord",
"domain": domain,
@@ -110,7 +111,7 @@ func (this *CustomHTTPProvider) AddRecord(domain string, newRecord *Record) erro
}
// UpdateRecord 修改记录
func (this *CustomHTTPProvider) UpdateRecord(domain string, record *Record, newRecord *Record) error {
func (this *CustomHTTPProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
_, err := this.post(maps.Map{
"action": "UpdateRecord",
"domain": domain,
@@ -121,7 +122,7 @@ func (this *CustomHTTPProvider) UpdateRecord(domain string, record *Record, newR
}
// DeleteRecord 删除记录
func (this *CustomHTTPProvider) DeleteRecord(domain string, record *Record) error {
func (this *CustomHTTPProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
_, err := this.post(maps.Map{
"action": "DeleteRecord",
"domain": domain,

View File

@@ -1,6 +1,7 @@
package dnsclients
import (
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
"testing"
@@ -15,10 +16,10 @@ func TestCustomHTTPProvider_AddRecord(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = provider.AddRecord("hello.com", &Record{
err = provider.AddRecord("hello.com", &dnstypes.Record{
Id: "",
Name: "world",
Type: RecordTypeA,
Type: dnstypes.RecordTypeA,
Value: "127.0.0.1",
Route: "default",
})

View File

@@ -3,6 +3,7 @@ package dnsclients
import (
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
@@ -35,7 +36,7 @@ func (this *DNSPodProvider) Auth(params maps.Map) error {
}
// GetRecords 获取域名列表
func (this *DNSPodProvider) GetRecords(domain string) (records []*Record, err error) {
func (this *DNSPodProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
offset := 0
size := 100
for {
@@ -53,7 +54,7 @@ func (this *DNSPodProvider) GetRecords(domain string) (records []*Record, err er
recordSlice := recordsResp.GetSlice("records")
for _, record := range recordSlice {
recordMap := maps.NewMap(record)
records = append(records, &Record{
records = append(records, &dnstypes.Record{
Id: recordMap.GetString("id"),
Name: recordMap.GetString("name"),
Type: recordMap.GetString("type"),
@@ -73,7 +74,7 @@ func (this *DNSPodProvider) GetRecords(domain string) (records []*Record, err er
}
// GetRoutes 读取线路数据
func (this *DNSPodProvider) GetRoutes(domain string) (routes []*Route, err error) {
func (this *DNSPodProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
infoResp, err := this.post("/Domain.info", map[string]string{
"domain": domain,
})
@@ -97,7 +98,7 @@ func (this *DNSPodProvider) GetRoutes(domain string) (routes []*Route, err error
}
for _, line := range lines {
lineString := types.String(line)
routes = append(routes, &Route{
routes = append(routes, &dnstypes.Route{
Name: lineString,
Code: lineString,
})
@@ -107,7 +108,7 @@ func (this *DNSPodProvider) GetRoutes(domain string) (routes []*Route, err error
}
// QueryRecord 查询单个记录
func (this *DNSPodProvider) QueryRecord(domain string, name string, recordType RecordType) (*Record, error) {
func (this *DNSPodProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
records, err := this.GetRecords(domain)
if err != nil {
return nil, err
@@ -121,13 +122,13 @@ func (this *DNSPodProvider) QueryRecord(domain string, name string, recordType R
}
// AddRecord 设置记录
func (this *DNSPodProvider) AddRecord(domain string, newRecord *Record) error {
func (this *DNSPodProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
if newRecord == nil {
return errors.New("invalid new record")
}
// 在CHANGE记录后面加入点
if newRecord.Type == RecordTypeCName && !strings.HasSuffix(newRecord.Value, ".") {
if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
newRecord.Value += "."
}
_, err := this.post("/Record.Create", map[string]string{
@@ -141,7 +142,7 @@ func (this *DNSPodProvider) AddRecord(domain string, newRecord *Record) error {
}
// UpdateRecord 修改记录
func (this *DNSPodProvider) UpdateRecord(domain string, record *Record, newRecord *Record) error {
func (this *DNSPodProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
if record == nil {
return errors.New("invalid record")
}
@@ -150,7 +151,7 @@ func (this *DNSPodProvider) UpdateRecord(domain string, record *Record, newRecor
}
// 在CHANGE记录后面加入点
if newRecord.Type == RecordTypeCName && !strings.HasSuffix(newRecord.Value, ".") {
if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
newRecord.Value += "."
}
_, err := this.post("/Record.Modify", map[string]string{
@@ -165,7 +166,7 @@ func (this *DNSPodProvider) UpdateRecord(domain string, record *Record, newRecor
}
// DeleteRecord 删除记录
func (this *DNSPodProvider) DeleteRecord(domain string, record *Record) error {
func (this *DNSPodProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
if record == nil {
return errors.New("invalid record to delete")
}

View File

@@ -2,6 +2,7 @@ package dnsclients
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
@@ -40,8 +41,8 @@ func TestDNSPodProvider_AddRecord(t *testing.T) {
t.Fatal(err)
}
err = provider.AddRecord("yun4s.cn", &Record{
Type: RecordTypeCName,
err = provider.AddRecord("yun4s.cn", &dnstypes.Record{
Type: dnstypes.RecordTypeCNAME,
Name: "hello-forward",
Value: "hello.yun4s.cn",
Route: "联通",
@@ -58,10 +59,10 @@ func TestDNSPodProvider_UpdateRecord(t *testing.T) {
t.Fatal(err)
}
err = provider.UpdateRecord("yun4s.cn", &Record{
err = provider.UpdateRecord("yun4s.cn", &dnstypes.Record{
Id: "697036856",
}, &Record{
Type: RecordTypeA,
}, &dnstypes.Record{
Type: dnstypes.RecordTypeA,
Name: "hello",
Value: "192.168.1.102",
Route: "联通",
@@ -78,7 +79,7 @@ func TestDNSPodProvider_DeleteRecord(t *testing.T) {
t.Fatal(err)
}
err = provider.DeleteRecord("yun4s.cn", &Record{
err = provider.DeleteRecord("yun4s.cn", &dnstypes.Record{
Id: "697040986",
})
if err != nil {

View File

@@ -1,6 +1,9 @@
package dnsclients
import "github.com/iwind/TeaGo/maps"
import (
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/iwind/TeaGo/maps"
)
// ProviderInterface DNS操作接口
type ProviderInterface interface {
@@ -8,22 +11,22 @@ type ProviderInterface interface {
Auth(params maps.Map) error
// GetRecords 获取域名解析记录列表
GetRecords(domain string) (records []*Record, err error)
GetRecords(domain string) (records []*dnstypes.Record, err error)
// GetRoutes 读取域名支持的线路数据
GetRoutes(domain string) (routes []*Route, err error)
GetRoutes(domain string) (routes []*dnstypes.Route, err error)
// QueryRecord 查询单个记录
QueryRecord(domain string, name string, recordType RecordType) (*Record, error)
QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error)
// AddRecord 设置记录
AddRecord(domain string, newRecord *Record) error
AddRecord(domain string, newRecord *dnstypes.Record) error
// UpdateRecord 修改记录
UpdateRecord(domain string, record *Record, newRecord *Record) error
UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error
// DeleteRecord 删除记录
DeleteRecord(domain string, record *Record) error
DeleteRecord(domain string, record *dnstypes.Record) error
// DefaultRoute 默认线路
DefaultRoute() string

View File

@@ -0,0 +1,246 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package dnsclients
import (
"fmt"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"regexp"
"strings"
)
type LocalEdgeDNSProvider struct {
clusterId int64 // 集群ID
ttl int32 // TTL
}
// Auth 认证
func (this *LocalEdgeDNSProvider) Auth(params maps.Map) error {
this.clusterId = params.GetInt64("clusterId")
if this.clusterId <= 0 {
return errors.New("'clusterId' should be greater than 0")
}
this.ttl = params.GetInt32("ttl")
if this.ttl <= 0 {
this.ttl = 3600
}
return nil
}
// GetRecords 获取域名解析记录列表
func (this *LocalEdgeDNSProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
var tx *dbs.Tx
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, this.clusterId, domain)
if err != nil {
return nil, err
}
if domainId == 0 {
return nil, errors.New("can not find domain '" + domain + "'")
}
offset := int64(0)
size := int64(1000)
for {
result, err := nameservers.SharedNSRecordDAO.ListEnabledRecords(tx, domainId, "", "", 0, offset, size)
if err != nil {
return nil, err
}
if len(result) == 0 {
break
}
for _, record := range result {
if record.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(record.Value, ".") {
record.Value += "."
}
routeIds := record.DecodeRouteIds()
var routeIdString = ""
if len(routeIds) > 0 {
routeIdString = fmt.Sprintf("%d", routeIds[0])
}
records = append(records, &dnstypes.Record{
Id: fmt.Sprintf("%d", record.Id),
Name: record.Name,
Type: record.Type,
Value: record.Value,
Route: routeIdString,
})
}
offset += size
}
return
}
// GetRoutes 读取域名支持的线路数据
func (this *LocalEdgeDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
var tx *dbs.Tx
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, this.clusterId, domain)
if err != nil {
return nil, err
}
if domainId == 0 {
return nil, errors.New("can not find domain '" + domain + "'")
}
// TODO 将来支持集群、域名、用户自定义线路
result, err := nameservers.SharedNSRouteDAO.FindAllEnabledRoutes(tx, 0, 0, 0)
if err != nil {
return nil, err
}
for _, route := range result {
routes = append(routes, &dnstypes.Route{
Name: route.Name,
Code: fmt.Sprintf("%d", route.Id),
})
}
return
}
// QueryRecord 查询单个记录
func (this *LocalEdgeDNSProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
var tx *dbs.Tx
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, this.clusterId, domain)
if err != nil {
return nil, err
}
if domainId == 0 {
return nil, nil
}
record, err := nameservers.SharedNSRecordDAO.FindEnabledRecordWithName(tx, domainId, name, recordType)
if err != nil {
return nil, err
}
if record == nil {
return nil, nil
}
routeIds := record.DecodeRouteIds()
var routeIdString = ""
if len(routeIds) > 0 {
routeIdString = fmt.Sprintf("%d", routeIds[0])
}
return &dnstypes.Record{
Id: fmt.Sprintf("%d", record.Id),
Name: record.Name,
Type: record.Type,
Value: record.Value,
Route: routeIdString,
}, nil
}
// AddRecord 设置记录
func (this *LocalEdgeDNSProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
var tx *dbs.Tx
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, this.clusterId, domain)
if err != nil {
return err
}
if domainId == 0 {
return errors.New("can not find domain '" + domain + "'")
}
var routeIds []int64
if len(newRecord.Route) > 0 && regexp.MustCompile(`^\d+$`).MatchString(newRecord.Route) {
routeId := types.Int64(newRecord.Route)
if routeId > 0 {
routeIds = append(routeIds, routeId)
}
}
_, err = nameservers.SharedNSRecordDAO.CreateRecord(tx, domainId, "", newRecord.Name, newRecord.Type, newRecord.Value, this.ttl, routeIds)
if err != nil {
return err
}
return nil
}
// UpdateRecord 修改记录
func (this *LocalEdgeDNSProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
var tx *dbs.Tx
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, this.clusterId, domain)
if err != nil {
return err
}
if domainId == 0 {
return errors.New("can not find domain '" + domain + "'")
}
var routeIds []int64
if len(newRecord.Route) > 0 && regexp.MustCompile(`^\d+$`).MatchString(newRecord.Route) {
routeId := types.Int64(newRecord.Route)
if routeId > 0 {
routeIds = append(routeIds, routeId)
}
}
if len(record.Id) > 0 {
err = nameservers.SharedNSRecordDAO.UpdateRecord(tx, types.Int64(record.Id), "", newRecord.Name, newRecord.Type, newRecord.Value, this.ttl, routeIds)
if err != nil {
return err
}
} else {
realRecord, err := nameservers.SharedNSRecordDAO.FindEnabledRecordWithName(tx, domainId, record.Name, record.Type)
if err != nil {
return err
}
if realRecord != nil {
err = nameservers.SharedNSRecordDAO.UpdateRecord(tx, types.Int64(realRecord.Id), "", newRecord.Name, newRecord.Type, newRecord.Value, this.ttl, routeIds)
if err != nil {
return err
}
}
}
return nil
}
// DeleteRecord 删除记录
func (this *LocalEdgeDNSProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
var tx *dbs.Tx
domainId, err := nameservers.SharedNSDomainDAO.FindDomainIdWithName(tx, this.clusterId, domain)
if err != nil {
return err
}
if domainId == 0 {
return errors.New("can not find domain '" + domain + "'")
}
if len(record.Id) > 0 {
err = nameservers.SharedNSRecordDAO.DisableNSRecord(tx, types.Int64(record.Id))
if err != nil {
return err
}
} else {
realRecord, err := nameservers.SharedNSRecordDAO.FindEnabledRecordWithName(tx, domainId, record.Name, record.Type)
if err != nil {
return err
}
if realRecord != nil {
err = nameservers.SharedNSRecordDAO.DisableNSRecord(tx, types.Int64(realRecord.Id))
if err != nil {
return err
}
}
}
return nil
}
// DefaultRoute 默认线路
func (this *LocalEdgeDNSProvider) DefaultRoute() string {
return ""
}

View File

@@ -0,0 +1,160 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package dnsclients
import (
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
"testing"
)
func TestLocalEdgeDNSProvider_GetRecords(t *testing.T) {
dbs.NotifyReady()
provider := &LocalEdgeDNSProvider{}
err := provider.Auth(maps.Map{
"clusterId": 1,
})
if err != nil {
t.Fatal(err)
}
records, err := provider.GetRecords("teaos.cn")
if err != nil {
t.Fatal(err)
}
logs.PrintAsJSON(records, t)
}
func TestLocalEdgeDNSProvider_GetRoutes(t *testing.T) {
dbs.NotifyReady()
provider := &LocalEdgeDNSProvider{}
err := provider.Auth(maps.Map{
"clusterId": 1,
})
if err != nil {
t.Fatal(err)
}
routes, err := provider.GetRoutes("teaos.cn")
if err != nil {
t.Fatal(err)
}
logs.PrintAsJSON(routes, t)
}
func TestLocalEdgeDNSProvider_QueryRecord(t *testing.T) {
dbs.NotifyReady()
provider := &LocalEdgeDNSProvider{}
err := provider.Auth(maps.Map{
"clusterId": 1,
})
if err != nil {
t.Fatal(err)
}
record, err := provider.QueryRecord("teaos.cn", "cdn", dnstypes.RecordTypeA)
if err != nil {
t.Fatal(err)
}
logs.PrintAsJSON(record)
}
func TestLocalEdgeDNSProvider_AddRecord(t *testing.T) {
dbs.NotifyReady()
provider := &LocalEdgeDNSProvider{}
err := provider.Auth(maps.Map{
"clusterId": 1,
})
if err != nil {
t.Fatal(err)
}
err = provider.AddRecord("teaos.cn", &dnstypes.Record{
Id: "",
Name: "example",
Type: dnstypes.RecordTypeA,
Value: "10.0.0.1",
Route: "7",
})
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}
func TestLocalEdgeDNSProvider_UpdateRecord(t *testing.T) {
dbs.NotifyReady()
provider := &LocalEdgeDNSProvider{}
err := provider.Auth(maps.Map{
"clusterId": 1,
})
if err != nil {
t.Fatal(err)
}
record, err := provider.QueryRecord("teaos.cn", "cdn", dnstypes.RecordTypeA)
if err != nil {
t.Fatal(err)
}
if record == nil {
t.Log("not found record")
return
}
//record.Id = ""
err = provider.UpdateRecord("teaos.cn", record, &dnstypes.Record{
Id: "",
Name: record.Name,
Type: record.Type,
Value: "127.0.0.3",
Route: record.Route,
})
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}
func TestLocalEdgeDNSProvider_DeleteRecord(t *testing.T) {
dbs.NotifyReady()
provider := &LocalEdgeDNSProvider{}
err := provider.Auth(maps.Map{
"clusterId": 1,
})
if err != nil {
t.Fatal(err)
}
err = provider.DeleteRecord("teaos.cn", &dnstypes.Record{
Id: "",
Name: "example",
Type: "A",
Value: "",
Route: "",
})
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}
func TestLocalEdgeDNSProvider_DefaultRoute(t *testing.T) {
dbs.NotifyReady()
provider := &LocalEdgeDNSProvider{}
err := provider.Auth(maps.Map{
"clusterId": 1,
})
if err != nil {
t.Fatal(err)
}
t.Log(provider.DefaultRoute())
}

View File

@@ -0,0 +1,59 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package dnsclients
import (
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
"github.com/iwind/TeaGo/maps"
)
type UserEdgeDNSProvider struct {
}
// Auth 认证
func (this *UserEdgeDNSProvider) Auth(params maps.Map) error {
// TODO
return nil
}
// GetRecords 获取域名解析记录列表
func (this *UserEdgeDNSProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
// TODO
return
}
// GetRoutes 读取域名支持的线路数据
func (this *UserEdgeDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
// TODO
return
}
// QueryRecord 查询单个记录
func (this *UserEdgeDNSProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
// TODO
return nil, nil
}
// AddRecord 设置记录
func (this *UserEdgeDNSProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
// TODO
return nil
}
// UpdateRecord 修改记录
func (this *UserEdgeDNSProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
// TODO
return nil
}
// DeleteRecord 删除记录
func (this *UserEdgeDNSProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
// TODO
return nil
}
// DefaultRoute 默认线路
func (this *UserEdgeDNSProvider) DefaultRoute() string {
// TODO
return ""
}

View File

@@ -1,40 +1,70 @@
package dnsclients
import "github.com/iwind/TeaGo/maps"
import (
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/iwind/TeaGo/maps"
)
type ProviderType = string
// 服务商代号
const (
ProviderTypeDNSPod ProviderType = "dnspod"
ProviderTypeAliDNS ProviderType = "alidns"
ProviderTypeDNSCom ProviderType = "dnscom"
ProviderTypeCloudFlare ProviderType = "cloudFlare"
ProviderTypeCustomHTTP ProviderType = "customHTTP"
ProviderTypeDNSPod ProviderType = "dnspod" // DNSPod
ProviderTypeAliDNS ProviderType = "alidns" // 阿里云DNS
ProviderTypeDNSCom ProviderType = "dnscom" // dns.com
ProviderTypeCloudFlare ProviderType = "cloudFlare" // CloudFlare DNS
ProviderTypeLocalEdgeDNS ProviderType = "localEdgeDNS" // 和当前系统集成的EdgeDNS
ProviderTypeUserEdgeDNS ProviderType = "userEdgeDNS" // 通过API连接的EdgeDNS
ProviderTypeCustomHTTP ProviderType = "customHTTP" // 自定义HTTP接口
)
// AllProviderTypes 所有的服务商类型
var AllProviderTypes = []maps.Map{
{
"name": "阿里云DNS",
"code": ProviderTypeAliDNS,
},
{
"name": "DNSPod",
"code": ProviderTypeDNSPod,
},
/**{
"name": "帝恩思DNS.COM",
"code": ProviderTypeDNSCom,
},**/
{
"name": "CloudFlare DNS",
"code": ProviderTypeCloudFlare,
},
{
"name": "自定义HTTP DNS",
"code": ProviderTypeCustomHTTP,
},
// FindAllProviderTypes 所有的服务商类型
func FindAllProviderTypes() []maps.Map {
typeMaps := []maps.Map{
{
"name": "阿里云DNS",
"code": ProviderTypeAliDNS,
"description": "阿里云提供的DNS服务。",
},
{
"name": "DNSPod",
"code": ProviderTypeDNSPod,
"description": "DNSPod提供的DNS服务。",
},
/**{
"name": "帝恩思DNS.COM",
"code": ProviderTypeDNSCom,
"description": "DNS.com提供的DNS服务。",
},**/
{
"name": "CloudFlare DNS",
"code": ProviderTypeCloudFlare,
"description": "CloudFlare提供的DNS服务。",
},
}
if teaconst.IsPlus {
typeMaps = append(typeMaps, []maps.Map{
{
"name": "集成EdgeDNS",
"code": ProviderTypeLocalEdgeDNS,
"description": "当前企业版提供的DNS服务。",
},
// TODO 需要实现用户使用AccessId/AccessKey来连接DNS服务
/**{
"name": "用户EdgeDNS",
"code": ProviderTypeUserEdgeDNS,
"description": "通过API连接企业版提供的DNS服务。",
},**/
}...)
}
typeMaps = append(typeMaps, maps.Map{
"name": "自定义HTTP DNS",
"code": ProviderTypeCustomHTTP,
"description": "通过自定义的HTTP接口提供DNS服务。",
})
return typeMaps
}
// FindProvider 查找服务商实例
@@ -46,6 +76,10 @@ func FindProvider(providerType ProviderType) ProviderInterface {
return &AliDNSProvider{}
case ProviderTypeCloudFlare:
return &CloudFlareProvider{}
case ProviderTypeLocalEdgeDNS:
return &LocalEdgeDNSProvider{}
case ProviderTypeUserEdgeDNS:
return &UserEdgeDNSProvider{}
case ProviderTypeCustomHTTP:
return &CustomHTTPProvider{}
}
@@ -54,7 +88,7 @@ func FindProvider(providerType ProviderType) ProviderInterface {
// FindProviderTypeName 查找服务商名称
func FindProviderTypeName(providerType ProviderType) string {
for _, t := range AllProviderTypes {
for _, t := range FindAllProviderTypes() {
if t.GetString("code") == providerType {
return t.GetString("name")
}

View File

@@ -0,0 +1,79 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package installers
import (
"crypto/md5"
"fmt"
"io"
"os"
)
// DeployFile 部署文件描述
type DeployFile struct {
OS string
Arch string
Version string
Path string
}
// Sum 计算概要
func (this *DeployFile) Sum() (string, error) {
fp, err := os.Open(this.Path)
if err != nil {
return "", err
}
defer func() {
_ = fp.Close()
}()
m := md5.New()
buffer := make([]byte, 128*1024)
for {
n, err := fp.Read(buffer)
if err != nil {
if err == io.EOF {
break
}
return "", err
}
_, err = m.Write(buffer[:n])
if err != nil {
return "", err
}
}
sum := m.Sum(nil)
return fmt.Sprintf("%x", sum), nil
}
// Read 读取一个片段数据
func (this *DeployFile) Read(offset int64) (data []byte, newOffset int64, err error) {
fp, err := os.Open(this.Path)
if err != nil {
return nil, offset, err
}
defer func() {
_ = fp.Close()
}()
stat, err := fp.Stat()
if err != nil {
return nil, offset, err
}
if offset >= stat.Size() {
return nil, offset, io.EOF
}
_, err = fp.Seek(offset, io.SeekStart)
if err != nil {
return nil, offset, err
}
buffer := make([]byte, 128*1024)
n, err := fp.Read(buffer)
if err != nil {
return nil, offset, err
}
return buffer[:n], offset + int64(n), nil
}

View File

@@ -0,0 +1,36 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package installers
import (
"io"
"testing"
)
func TestDeployFile_Sum(t *testing.T) {
d := &DeployFile{Path: "deploy_test.txt"}
sum, err := d.Sum()
if err != nil {
t.Log("err:", err)
return
}
t.Log("sum:", sum)
}
func TestDeployFile_Read(t *testing.T) {
d := &DeployFile{Path: "deploy_test.txt"}
var offset int64
for i := 0; i < 3; i++ {
data, newOffset, err := d.Read(offset)
if err != nil {
if err == io.EOF {
break
}
t.Log("err: ", err)
return
}
t.Log("offset:", newOffset, "data:", string(data))
offset = newOffset
}
}

View File

@@ -9,28 +9,67 @@ import (
var SharedDeployManager = NewDeployManager()
type DeployFile struct {
OS string
Arch string
Version string
Path string
}
type DeployManager struct {
dir string
}
// NewDeployManager 节点部署文件管理器
func NewDeployManager() *DeployManager {
return &DeployManager{
dir: Tea.Root + "/deploy",
}
}
// 加载所有文件
func (this *DeployManager) LoadFiles() []*DeployFile {
// LoadNodeFiles 加载所有边缘节点文件
func (this *DeployManager) LoadNodeFiles() []*DeployFile {
keyMap := map[string]*DeployFile{} // key => File
reg := regexp.MustCompile(`(\w+)-(\w+)-v([0-9.]+)\.zip`)
reg := regexp.MustCompile(`^edge-node-(\w+)-(\w+)-v([0-9.]+)\.zip$`)
for _, file := range files.NewFile(this.dir).List() {
name := file.Name()
if !reg.MatchString(name) {
continue
}
matches := reg.FindStringSubmatch(name)
osName := matches[1]
arch := matches[2]
version := matches[3]
key := osName + "_" + arch
oldFile, ok := keyMap[key]
if ok && stringutil.VersionCompare(oldFile.Version, version) > 0 {
continue
}
keyMap[key] = &DeployFile{
OS: osName,
Arch: arch,
Version: version,
Path: file.Path(),
}
}
result := []*DeployFile{}
for _, v := range keyMap {
result = append(result, v)
}
return result
}
// FindNodeFile 查找特别平台的节点文件
func (this *DeployManager) FindNodeFile(os string, arch string) *DeployFile {
for _, file := range this.LoadNodeFiles() {
if file.OS == os && file.Arch == arch {
return file
}
}
return nil
}
// LoadNSNodeFiles 加载所有文件
func (this *DeployManager) LoadNSNodeFiles() []*DeployFile {
keyMap := map[string]*DeployFile{} // key => File
reg := regexp.MustCompile(`^edge-dns-(\w+)-(\w+)-v([0-9.]+)\.zip$`)
for _, file := range files.NewFile(this.dir).List() {
name := file.Name()
if !reg.MatchString(name) {

View File

@@ -2,8 +2,16 @@ package installers
import "testing"
func TestDeployManager_LoadFiles(t *testing.T) {
files := NewDeployManager().LoadFiles()
func TestDeployManager_LoadNodeFiles(t *testing.T) {
files := NewDeployManager().LoadNodeFiles()
for _, file := range files {
t.Logf("%#v", file)
}
}
func TestDeployManager_LoadNSNodeFiles(t *testing.T) {
files := NewDeployManager().LoadNSNodeFiles()
for _, file := range files {
t.Logf("%#v", file)
}

View File

@@ -7,7 +7,7 @@ import (
func TestQueue_InstallNode(t *testing.T) {
queue := NewQueue()
err := queue.InstallNodeProcess(16)
err := queue.InstallNodeProcess(16, false)
if err != nil {
t.Fatal(err)
}

View File

@@ -9,10 +9,8 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/events"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
"github.com/TeaOSLab/EdgeAPI/internal/setup"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/go-yaml/yaml"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
@@ -29,16 +27,21 @@ import (
"os/exec"
"regexp"
"strconv"
"sync"
"time"
)
var sharedAPIConfig *configs.APIConfig = nil
type APINode struct {
serviceInstanceMap map[string]interface{}
serviceInstanceLocker sync.Mutex
}
func NewAPINode() *APINode {
return &APINode{}
return &APINode{
serviceInstanceMap: map[string]interface{}{},
}
}
func (this *APINode) Start() {
@@ -188,85 +191,7 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err
logs.Println("[API_NODE]listening GRPC https://" + listener.Addr().String() + " ...")
rpcServer = grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConfig)))
}
pb.RegisterAdminServiceServer(rpcServer, &services.AdminService{})
pb.RegisterNodeGrantServiceServer(rpcServer, &services.NodeGrantService{})
pb.RegisterServerServiceServer(rpcServer, &services.ServerService{})
pb.RegisterNodeServiceServer(rpcServer, &services.NodeService{})
pb.RegisterNodeClusterServiceServer(rpcServer, &services.NodeClusterService{})
pb.RegisterNodeIPAddressServiceServer(rpcServer, &services.NodeIPAddressService{})
pb.RegisterAPINodeServiceServer(rpcServer, &services.APINodeService{})
pb.RegisterOriginServiceServer(rpcServer, &services.OriginService{})
pb.RegisterHTTPWebServiceServer(rpcServer, &services.HTTPWebService{})
pb.RegisterReverseProxyServiceServer(rpcServer, &services.ReverseProxyService{})
pb.RegisterHTTPGzipServiceServer(rpcServer, &services.HTTPGzipService{})
pb.RegisterHTTPHeaderPolicyServiceServer(rpcServer, &services.HTTPHeaderPolicyService{})
pb.RegisterHTTPHeaderServiceServer(rpcServer, &services.HTTPHeaderService{})
pb.RegisterHTTPPageServiceServer(rpcServer, &services.HTTPPageService{})
pb.RegisterHTTPAccessLogPolicyServiceServer(rpcServer, &services.HTTPAccessLogPolicyService{})
pb.RegisterHTTPCachePolicyServiceServer(rpcServer, &services.HTTPCachePolicyService{})
pb.RegisterHTTPFirewallPolicyServiceServer(rpcServer, &services.HTTPFirewallPolicyService{})
pb.RegisterHTTPLocationServiceServer(rpcServer, &services.HTTPLocationService{})
pb.RegisterHTTPWebsocketServiceServer(rpcServer, &services.HTTPWebsocketService{})
pb.RegisterHTTPRewriteRuleServiceServer(rpcServer, &services.HTTPRewriteRuleService{})
pb.RegisterSSLCertServiceServer(rpcServer, &services.SSLCertService{})
pb.RegisterSSLPolicyServiceServer(rpcServer, &services.SSLPolicyService{})
pb.RegisterSysSettingServiceServer(rpcServer, &services.SysSettingService{})
pb.RegisterHTTPFirewallRuleGroupServiceServer(rpcServer, &services.HTTPFirewallRuleGroupService{})
pb.RegisterHTTPFirewallRuleSetServiceServer(rpcServer, &services.HTTPFirewallRuleSetService{})
pb.RegisterDBNodeServiceServer(rpcServer, &services.DBNodeService{})
pb.RegisterNodeLogServiceServer(rpcServer, &services.NodeLogService{})
pb.RegisterHTTPAccessLogServiceServer(rpcServer, &services.HTTPAccessLogService{})
pb.RegisterMessageServiceServer(rpcServer, &services.MessageService{})
pb.RegisterMessageRecipientServiceServer(rpcServer, &services.MessageRecipientService{})
pb.RegisterMessageReceiverServiceServer(rpcServer, &services.MessageReceiverService{})
pb.RegisterMessageMediaServiceServer(rpcServer, &services.MessageMediaService{})
pb.RegisterMessageRecipientGroupServiceServer(rpcServer, &services.MessageRecipientGroupService{})
pb.RegisterMessageMediaInstanceServiceServer(rpcServer, &services.MessageMediaInstanceService{})
pb.RegisterMessageTaskServiceServer(rpcServer, &services.MessageTaskService{})
pb.RegisterMessageTaskLogServiceServer(rpcServer, &services.MessageTaskLogService{})
pb.RegisterNodeGroupServiceServer(rpcServer, &services.NodeGroupService{})
pb.RegisterNodeRegionServiceServer(rpcServer, &services.NodeRegionService{})
pb.RegisterNodePriceItemServiceServer(rpcServer, &services.NodePriceItemService{})
pb.RegisterServerGroupServiceServer(rpcServer, &services.ServerGroupService{})
pb.RegisterIPLibraryServiceServer(rpcServer, &services.IPLibraryService{})
pb.RegisterFileChunkServiceServer(rpcServer, &services.FileChunkService{})
pb.RegisterFileServiceServer(rpcServer, &services.FileService{})
pb.RegisterRegionCountryServiceServer(rpcServer, &services.RegionCountryService{})
pb.RegisterRegionProvinceServiceServer(rpcServer, &services.RegionProvinceService{})
pb.RegisterIPListServiceServer(rpcServer, &services.IPListService{})
pb.RegisterIPItemServiceServer(rpcServer, &services.IPItemService{})
pb.RegisterLogServiceServer(rpcServer, &services.LogService{})
pb.RegisterDNSProviderServiceServer(rpcServer, &services.DNSProviderService{})
pb.RegisterDNSDomainServiceServer(rpcServer, &services.DNSDomainService{})
pb.RegisterDNSServiceServer(rpcServer, &services.DNSService{})
pb.RegisterACMEUserServiceServer(rpcServer, &services.ACMEUserService{})
pb.RegisterACMETaskServiceServer(rpcServer, &services.ACMETaskService{})
pb.RegisterACMEAuthenticationServiceServer(rpcServer, &services.ACMEAuthenticationService{})
pb.RegisterUserServiceServer(rpcServer, &services.UserService{})
pb.RegisterServerDailyStatServiceServer(rpcServer, &services.ServerDailyStatService{})
pb.RegisterUserBillServiceServer(rpcServer, &services.UserBillService{})
pb.RegisterUserNodeServiceServer(rpcServer, &services.UserNodeService{})
pb.RegisterLoginServiceServer(rpcServer, &services.LoginService{})
pb.RegisterUserAccessKeyServiceServer(rpcServer, &services.UserAccessKeyService{})
pb.RegisterSysLockerServiceServer(rpcServer, &services.SysLockerService{})
pb.RegisterNodeTaskServiceServer(rpcServer, &services.NodeTaskService{})
pb.RegisterNodeValueServiceServer(rpcServer, &services.NodeValueService{})
pb.RegisterDBServiceServer(rpcServer, &services.DBService{})
pb.RegisterServerRegionCityMonthlyStatServiceServer(rpcServer, &services.ServerRegionCityMonthlyStatService{})
pb.RegisterServerRegionCountryMonthlyStatServiceServer(rpcServer, &services.ServerRegionCountryMonthlyStatService{})
pb.RegisterServerRegionProvinceMonthlyStatServiceServer(rpcServer, &services.ServerRegionProvinceMonthlyStatService{})
pb.RegisterServerRegionProviderMonthlyStatServiceServer(rpcServer, &services.ServerRegionProviderMonthlyStatService{})
pb.RegisterServerClientSystemMonthlyStatServiceServer(rpcServer, &services.ServerClientSystemMonthlyStatService{})
pb.RegisterServerClientBrowserMonthlyStatServiceServer(rpcServer, &services.ServerClientBrowserMonthlyStatService{})
pb.RegisterServerHTTPFirewallDailyStatServiceServer(rpcServer, &services.ServerHTTPFirewallDailyStatService{})
pb.RegisterDNSTaskServiceServer(rpcServer, &services.DNSTaskService{})
pb.RegisterNodeClusterFirewallActionServiceServer(rpcServer, &services.NodeClusterFirewallActionService{})
pb.RegisterMonitorNodeServiceServer(rpcServer, &services.MonitorNodeService{})
pb.RegisterAuthorityKeyServiceServer(rpcServer, &services.AuthorityKeyService{})
pb.RegisterAuthorityNodeServiceServer(rpcServer, &services.AuthorityNodeService{})
pb.RegisterLatestItemServiceServer(rpcServer, &services.LatestItemService{})
pb.RegisterNodeThresholdServiceServer(rpcServer, &services.NodeThresholdService{})
pb.RegisterHTTPFastcgiServiceServer(rpcServer, &services.HTTPFastcgiService{})
this.registerServices(rpcServer)
err := rpcServer.Serve(listener)
if err != nil {
return errors.New("[API_NODE]start rpc failed: " + err.Error())

View File

@@ -0,0 +1,489 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package nodes
import (
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services/nameservers"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"google.golang.org/grpc"
"reflect"
"strings"
)
// 注册服务
func (this *APINode) registerServices(server *grpc.Server) {
{
instance := this.serviceInstance(&services.AdminService{}).(*services.AdminService)
pb.RegisterAdminServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeGrantService{}).(*services.NodeGrantService)
pb.RegisterNodeGrantServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerService{}).(*services.ServerService)
pb.RegisterServerServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeService{}).(*services.NodeService)
pb.RegisterNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeClusterService{}).(*services.NodeClusterService)
pb.RegisterNodeClusterServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeIPAddressService{}).(*services.NodeIPAddressService)
pb.RegisterNodeIPAddressServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.APINodeService{}).(*services.APINodeService)
pb.RegisterAPINodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.OriginService{}).(*services.OriginService)
pb.RegisterOriginServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPWebService{}).(*services.HTTPWebService)
pb.RegisterHTTPWebServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ReverseProxyService{}).(*services.ReverseProxyService)
pb.RegisterReverseProxyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPGzipService{}).(*services.HTTPGzipService)
pb.RegisterHTTPGzipServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPHeaderPolicyService{}).(*services.HTTPHeaderPolicyService)
pb.RegisterHTTPHeaderPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPHeaderService{}).(*services.HTTPHeaderService)
pb.RegisterHTTPHeaderServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPPageService{}).(*services.HTTPPageService)
pb.RegisterHTTPPageServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPAccessLogPolicyService{}).(*services.HTTPAccessLogPolicyService)
pb.RegisterHTTPAccessLogPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPCachePolicyService{}).(*services.HTTPCachePolicyService)
pb.RegisterHTTPCachePolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPFirewallPolicyService{}).(*services.HTTPFirewallPolicyService)
pb.RegisterHTTPFirewallPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPLocationService{}).(*services.HTTPLocationService)
pb.RegisterHTTPLocationServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPWebsocketService{}).(*services.HTTPWebsocketService)
pb.RegisterHTTPWebsocketServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPRewriteRuleService{}).(*services.HTTPRewriteRuleService)
pb.RegisterHTTPRewriteRuleServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.SSLCertService{}).(*services.SSLCertService)
pb.RegisterSSLCertServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.SSLPolicyService{}).(*services.SSLPolicyService)
pb.RegisterSSLPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.SysSettingService{}).(*services.SysSettingService)
pb.RegisterSysSettingServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPFirewallRuleGroupService{}).(*services.HTTPFirewallRuleGroupService)
pb.RegisterHTTPFirewallRuleGroupServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPFirewallRuleSetService{}).(*services.HTTPFirewallRuleSetService)
pb.RegisterHTTPFirewallRuleSetServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DBNodeService{}).(*services.DBNodeService)
pb.RegisterDBNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeLogService{}).(*services.NodeLogService)
pb.RegisterNodeLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPAccessLogService{}).(*services.HTTPAccessLogService)
pb.RegisterHTTPAccessLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageService{}).(*services.MessageService)
pb.RegisterMessageServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageRecipientService{}).(*services.MessageRecipientService)
pb.RegisterMessageRecipientServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageReceiverService{}).(*services.MessageReceiverService)
pb.RegisterMessageReceiverServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageMediaService{}).(*services.MessageMediaService)
pb.RegisterMessageMediaServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageRecipientGroupService{}).(*services.MessageRecipientGroupService)
pb.RegisterMessageRecipientGroupServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageMediaInstanceService{}).(*services.MessageMediaInstanceService)
pb.RegisterMessageMediaInstanceServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageTaskService{}).(*services.MessageTaskService)
pb.RegisterMessageTaskServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MessageTaskLogService{}).(*services.MessageTaskLogService)
pb.RegisterMessageTaskLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeGroupService{}).(*services.NodeGroupService)
pb.RegisterNodeGroupServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeRegionService{}).(*services.NodeRegionService)
pb.RegisterNodeRegionServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodePriceItemService{}).(*services.NodePriceItemService)
pb.RegisterNodePriceItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerGroupService{}).(*services.ServerGroupService)
pb.RegisterServerGroupServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.IPLibraryService{}).(*services.IPLibraryService)
pb.RegisterIPLibraryServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.FileChunkService{}).(*services.FileChunkService)
pb.RegisterFileChunkServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.FileService{}).(*services.FileService)
pb.RegisterFileServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.RegionCountryService{}).(*services.RegionCountryService)
pb.RegisterRegionCountryServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.RegionProvinceService{}).(*services.RegionProvinceService)
pb.RegisterRegionProvinceServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.IPListService{}).(*services.IPListService)
pb.RegisterIPListServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.IPItemService{}).(*services.IPItemService)
pb.RegisterIPItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.LogService{}).(*services.LogService)
pb.RegisterLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DNSProviderService{}).(*services.DNSProviderService)
pb.RegisterDNSProviderServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DNSDomainService{}).(*services.DNSDomainService)
pb.RegisterDNSDomainServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DNSService{}).(*services.DNSService)
pb.RegisterDNSServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ACMEUserService{}).(*services.ACMEUserService)
pb.RegisterACMEUserServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ACMETaskService{}).(*services.ACMETaskService)
pb.RegisterACMETaskServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ACMEAuthenticationService{}).(*services.ACMEAuthenticationService)
pb.RegisterACMEAuthenticationServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserService{}).(*services.UserService)
pb.RegisterUserServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerDailyStatService{}).(*services.ServerDailyStatService)
pb.RegisterServerDailyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserBillService{}).(*services.UserBillService)
pb.RegisterUserBillServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserNodeService{}).(*services.UserNodeService)
pb.RegisterUserNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.LoginService{}).(*services.LoginService)
pb.RegisterLoginServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.UserAccessKeyService{}).(*services.UserAccessKeyService)
pb.RegisterUserAccessKeyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.SysLockerService{}).(*services.SysLockerService)
pb.RegisterSysLockerServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeTaskService{}).(*services.NodeTaskService)
pb.RegisterNodeTaskServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeValueService{}).(*services.NodeValueService)
pb.RegisterNodeValueServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DBService{}).(*services.DBService)
pb.RegisterDBServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerRegionCityMonthlyStatService{}).(*services.ServerRegionCityMonthlyStatService)
pb.RegisterServerRegionCityMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerRegionCountryMonthlyStatService{}).(*services.ServerRegionCountryMonthlyStatService)
pb.RegisterServerRegionCountryMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerRegionProvinceMonthlyStatService{}).(*services.ServerRegionProvinceMonthlyStatService)
pb.RegisterServerRegionProvinceMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerRegionProviderMonthlyStatService{}).(*services.ServerRegionProviderMonthlyStatService)
pb.RegisterServerRegionProviderMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerClientSystemMonthlyStatService{}).(*services.ServerClientSystemMonthlyStatService)
pb.RegisterServerClientSystemMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerClientBrowserMonthlyStatService{}).(*services.ServerClientBrowserMonthlyStatService)
pb.RegisterServerClientBrowserMonthlyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.ServerHTTPFirewallDailyStatService{}).(*services.ServerHTTPFirewallDailyStatService)
pb.RegisterServerHTTPFirewallDailyStatServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.DNSTaskService{}).(*services.DNSTaskService)
pb.RegisterDNSTaskServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeClusterFirewallActionService{}).(*services.NodeClusterFirewallActionService)
pb.RegisterNodeClusterFirewallActionServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MonitorNodeService{}).(*services.MonitorNodeService)
pb.RegisterMonitorNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.AuthorityKeyService{}).(*services.AuthorityKeyService)
pb.RegisterAuthorityKeyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.AuthorityNodeService{}).(*services.AuthorityNodeService)
pb.RegisterAuthorityNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.LatestItemService{}).(*services.LatestItemService)
pb.RegisterLatestItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeThresholdService{}).(*services.NodeThresholdService)
pb.RegisterNodeThresholdServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPFastcgiService{}).(*services.HTTPFastcgiService)
pb.RegisterHTTPFastcgiServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSClusterService{}).(*nameservers.NSClusterService)
pb.RegisterNSClusterServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSNodeService{}).(*nameservers.NSNodeService)
pb.RegisterNSNodeServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSDomainService{}).(*nameservers.NSDomainService)
pb.RegisterNSDomainServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSRecordService{}).(*nameservers.NSRecordService)
pb.RegisterNSRecordServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSRouteService{}).(*nameservers.NSRouteService)
pb.RegisterNSRouteServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&nameservers.NSAccessLogService{}).(*nameservers.NSAccessLogService)
pb.RegisterNSAccessLogServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.HTTPAuthPolicyService{}).(*services.HTTPAuthPolicyService)
pb.RegisterHTTPAuthPolicyServiceServer(server, instance)
this.rest(instance)
}
// TODO check service names
for serviceName := range server.GetServiceInfo() {
index := strings.LastIndex(serviceName, ".")
if index >= 0 {
serviceName = serviceName[index+1:]
}
_, ok := restServicesMap[serviceName]
if !ok {
panic("can not find service '" + serviceName + "' in rest")
}
}
}
func (this *APINode) rest(instance interface{}) {
this.serviceInstanceLocker.Lock()
defer this.serviceInstanceLocker.Unlock()
var name = reflect.TypeOf(instance).String()
index := strings.LastIndex(name, ".")
if index >= 0 {
name = name[index+1:]
}
_, ok := restServicesMap[name]
if ok {
return
}
restServicesMap[name] = reflect.ValueOf(instance)
}
func (this *APINode) serviceInstance(instance interface{}) interface{} {
this.serviceInstanceLocker.Lock()
defer this.serviceInstanceLocker.Unlock()
typeName := reflect.TypeOf(instance).String()
result, ok := this.serviceInstanceMap[typeName]
if ok {
return result
}
this.serviceInstanceMap[typeName] = instance
return instance
}

View File

@@ -13,14 +13,13 @@ import (
"net/http"
"reflect"
"regexp"
"strings"
"time"
)
var servicePathReg = regexp.MustCompile(`^/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)$`)
var servicesMap = map[string]reflect.Value{
var restServicesMap = map[string]reflect.Value{
"APIAccessTokenService": reflect.ValueOf(new(services.APIAccessTokenService)),
"HTTPAccessLogService": reflect.ValueOf(new(services.HTTPAccessLogService)),
"IPItemService": reflect.ValueOf(new(services.IPItemService)),
}
type RestServer struct{}
@@ -67,12 +66,19 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
serviceName := matches[1]
methodName := matches[2]
serviceType, ok := servicesMap[serviceName]
serviceType, ok := restServicesMap[serviceName]
if !ok {
writer.WriteHeader(http.StatusNotFound)
return
}
if len(methodName) == 0 {
writer.WriteHeader(http.StatusNotFound)
return
}
// 再次查找
methodName = strings.ToUpper(string(methodName[0])) + methodName[1:]
method := serviceType.MethodByName(methodName)
if !method.IsValid() {
writer.WriteHeader(http.StatusNotFound)
@@ -90,7 +96,7 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
// 上下文
ctx := context.Background()
if serviceName != "APIAccessTokenService" || methodName != "GetAPIAccessToken" {
if serviceName != "APIAccessTokenService" || (methodName != "GetAPIAccessToken" && methodName != "getAPIAccessToken") {
// 校验TOKEN
token := req.Header.Get("Edge-Access-Token")
if len(token) == 0 {
@@ -123,6 +129,8 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
if accessToken.UserId > 0 {
ctx = rpcutils.NewPlainContext("user", int64(accessToken.UserId))
} else if accessToken.AdminId > 0 {
ctx = rpcutils.NewPlainContext("admin", int64(accessToken.AdminId))
} else {
// TODO 支持更多类型的角色
this.writeJSON(writer, maps.Map{
@@ -147,7 +155,7 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
err = json.Unmarshal(body, reqValue)
if err != nil {
writer.WriteHeader(http.StatusBadRequest)
_, _ = writer.Write([]byte(err.Error()))
_, _ = writer.Write([]byte("Decode request failed: " + err.Error() + ". Request body should be a valid JSON data"))
return
}
@@ -187,13 +195,15 @@ func (this *RestServer) handle(writer http.ResponseWriter, req *http.Request) {
"data": maps.Map{},
}, shouldPretty)
} else {
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
_, _ = writer.Write(dataJSON)
}
}
}
func (this *RestServer) writeJSON(writer http.ResponseWriter, v maps.Map, pretty bool) {
writer.Header().Set("Content-Type", "application/json")
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
if pretty {
_, _ = writer.Write(v.AsPrettyJSON())

View File

@@ -4,6 +4,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/configs"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/logs"
"time"
@@ -99,7 +100,7 @@ Loop:
for {
select {
case log := <-logChan:
err := models.SharedNodeLogDAO.CreateLog(nil, models.NodeRoleAPI, log.NodeId, 0, log.Level, log.Tag, log.Description, log.CreatedAt)
err := models.SharedNodeLogDAO.CreateLog(nil, nodeconfigs.NodeRoleAPI, log.NodeId, 0, log.Level, log.Tag, log.Description, log.CreatedAt)
if err != nil {
return err
}

View File

@@ -0,0 +1,102 @@
package nameservers
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// NSAccessLogService 访问日志相关服务
type NSAccessLogService struct {
services.BaseService
}
// CreateNSAccessLogs 创建访问日志
func (this *NSAccessLogService) CreateNSAccessLogs(ctx context.Context, req *pb.CreateNSAccessLogsRequest) (*pb.CreateNSAccessLogsResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeDNS)
if err != nil {
return nil, err
}
if len(req.NsAccessLogs) == 0 {
return &pb.CreateNSAccessLogsResponse{}, nil
}
tx := this.NullTx()
err = models.SharedNSAccessLogDAO.CreateNSAccessLogs(tx, req.NsAccessLogs)
if err != nil {
return nil, err
}
return &pb.CreateNSAccessLogsResponse{}, nil
}
// ListNSAccessLogs 列出单页访问日志
func (this *NSAccessLogService) ListNSAccessLogs(ctx context.Context, req *pb.ListNSAccessLogsRequest) (*pb.ListNSAccessLogsResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
return nil, err
}
tx := this.NullTx()
// 检查服务ID
if userId > 0 {
// TODO
}
accessLogs, requestId, hasMore, err := models.SharedNSAccessLogDAO.ListAccessLogs(tx, req.RequestId, req.Size, req.Day, req.NsNodeId, req.NsDomainId, req.NsRecordId, req.Keyword, req.Reverse)
if err != nil {
return nil, err
}
result := []*pb.NSAccessLog{}
for _, accessLog := range accessLogs {
a, err := accessLog.ToPB()
if err != nil {
return nil, err
}
result = append(result, a)
}
return &pb.ListNSAccessLogsResponse{
NsAccessLogs: result,
HasMore: hasMore,
RequestId: requestId,
}, nil
}
// FindNSAccessLog 查找单个日志
func (this *NSAccessLogService) FindNSAccessLog(ctx context.Context, req *pb.FindNSAccessLogRequest) (*pb.FindNSAccessLogResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
return nil, err
}
tx := this.NullTx()
accessLog, err := models.SharedNSAccessLogDAO.FindAccessLogWithRequestId(tx, req.RequestId)
if err != nil {
return nil, err
}
if accessLog == nil {
return &pb.FindNSAccessLogResponse{NsAccessLog: nil}, nil
}
// 检查权限
if userId > 0 {
// TODO
}
a, err := accessLog.ToPB()
if err != nil {
return nil, err
}
return &pb.FindNSAccessLogResponse{NsAccessLog: a}, nil
}

View File

@@ -0,0 +1,169 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package nameservers
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/nameservers"
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// NSClusterService 域名服务集群相关服务
type NSClusterService struct {
services.BaseService
}
// CreateNSCluster 创建集群
func (this *NSClusterService) CreateNSCluster(ctx context.Context, req *pb.CreateNSClusterRequest) (*pb.CreateNSClusterResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
clusterId, err := nameservers.SharedNSClusterDAO.CreateCluster(tx, req.Name, req.AccessLogJSON)
if err != nil {
return nil, err
}
return &pb.CreateNSClusterResponse{NsClusterId: clusterId}, nil
}
// UpdateNSCluster 修改集群
func (this *NSClusterService) UpdateNSCluster(ctx context.Context, req *pb.UpdateNSClusterRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = nameservers.SharedNSClusterDAO.UpdateCluster(tx, req.NsClusterId, req.Name, req.IsOn)
if err != nil {
return nil, err
}
return this.Success()
}
// FindNSClusterAccessLog 查找集群访问日志配置
func (this *NSClusterService) FindNSClusterAccessLog(ctx context.Context, req *pb.FindNSClusterAccessLogRequest) (*pb.FindNSClusterAccessLogResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
accessLogJSON, err := nameservers.SharedNSClusterDAO.FindClusterAccessLog(tx, req.NsClusterId)
if err != nil {
return nil, err
}
return &pb.FindNSClusterAccessLogResponse{AccessLogJSON: accessLogJSON}, nil
}
// UpdateNSClusterAccessLog 修改集群访问日志配置
func (this *NSClusterService) UpdateNSClusterAccessLog(ctx context.Context, req *pb.UpdateNSClusterAccessLogRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = nameservers.SharedNSClusterDAO.UpdateClusterAccessLog(tx, req.NsClusterId, req.AccessLogJSON)
if err != nil {
return nil, err
}
return this.Success()
}
// DeleteNSCluster 删除集群
func (this *NSClusterService) DeleteNSCluster(ctx context.Context, req *pb.DeleteNSCluster) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = nameservers.SharedNSClusterDAO.DisableNSCluster(tx, req.NsClusterId)
if err != nil {
return nil, err
}
return this.Success()
}
// FindEnabledNSCluster 查找单个可用集群信息
func (this *NSClusterService) FindEnabledNSCluster(ctx context.Context, req *pb.FindEnabledNSClusterRequest) (*pb.FindEnabledNSClusterResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
cluster, err := nameservers.SharedNSClusterDAO.FindEnabledNSCluster(tx, req.NsClusterId)
if err != nil {
return nil, err
}
if cluster == nil {
return &pb.FindEnabledNSClusterResponse{NsCluster: nil}, nil
}
return &pb.FindEnabledNSClusterResponse{NsCluster: &pb.NSCluster{
Id: int64(cluster.Id),
IsOn: cluster.IsOn == 1,
Name: cluster.Name,
InstallDir: cluster.InstallDir,
}}, nil
}
// CountAllEnabledNSClusters 计算所有可用集群的数量
func (this *NSClusterService) CountAllEnabledNSClusters(ctx context.Context, req *pb.CountAllEnabledNSClustersRequest) (*pb.RPCCountResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
count, err := nameservers.SharedNSClusterDAO.CountAllEnabledClusters(tx)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// ListEnabledNSClusters 列出单页可用集群
func (this *NSClusterService) ListEnabledNSClusters(ctx context.Context, req *pb.ListEnabledNSClustersRequest) (*pb.ListEnabledNSClustersResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
clusters, err := nameservers.SharedNSClusterDAO.ListEnabledClusters(tx, req.Offset, req.Size)
if err != nil {
return nil, err
}
var pbClusters = []*pb.NSCluster{}
for _, cluster := range clusters {
pbClusters = append(pbClusters, &pb.NSCluster{
Id: int64(cluster.Id),
IsOn: cluster.IsOn == 1,
Name: cluster.Name,
InstallDir: cluster.InstallDir,
})
}
return &pb.ListEnabledNSClustersResponse{NsClusters: pbClusters}, nil
}
// FindAllEnabledNSClusters 查找所有可用集群
func (this *NSClusterService) FindAllEnabledNSClusters(ctx context.Context, req *pb.FindAllEnabledNSClustersRequest) (*pb.FindAllEnabledNSClustersResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
clusters, err := nameservers.SharedNSClusterDAO.FindAllEnabledClusters(tx)
if err != nil {
return nil, err
}
var pbClusters = []*pb.NSCluster{}
for _, cluster := range clusters {
pbClusters = append(pbClusters, &pb.NSCluster{
Id: int64(cluster.Id),
IsOn: cluster.IsOn == 1,
Name: cluster.Name,
InstallDir: cluster.InstallDir,
})
}
return &pb.FindAllEnabledNSClustersResponse{NsClusters: pbClusters}, nil
}

Some files were not shown because too many files have changed in this diff Show More