Files
EdgeAPI/internal/db/models/http_web_dao.go

606 lines
14 KiB
Go
Raw Normal View History

2020-09-15 14:44:11 +08:00
package models
import (
2020-09-17 10:16:00 +08:00
"encoding/json"
2020-09-15 14:44:11 +08:00
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
2020-10-06 21:02:15 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
2020-09-23 18:43:42 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
2020-09-15 14:44:11 +08:00
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
2020-10-20 20:18:06 +08:00
"github.com/iwind/TeaGo/lists"
2020-09-15 14:44:11 +08:00
"github.com/iwind/TeaGo/types"
2020-10-02 17:22:32 +08:00
"strconv"
2020-09-15 14:44:11 +08:00
)
const (
HTTPWebStateEnabled = 1 // 已启用
HTTPWebStateDisabled = 0 // 已禁用
)
type HTTPWebDAO dbs.DAO
func NewHTTPWebDAO() *HTTPWebDAO {
return dbs.NewDAO(&HTTPWebDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeHTTPWebs",
Model: new(HTTPWeb),
PkName: "id",
},
}).(*HTTPWebDAO)
}
2020-10-13 20:05:13 +08:00
var SharedHTTPWebDAO *HTTPWebDAO
func init() {
dbs.OnReady(func() {
SharedHTTPWebDAO = NewHTTPWebDAO()
})
}
2020-09-15 14:44:11 +08:00
2020-09-26 08:06:40 +08:00
func (this *HTTPWebDAO) Init() {
this.DAOObject.Init()
this.DAOObject.OnUpdate(func() error {
return SharedSysEventDAO.CreateEvent(NewServerChangeEvent())
})
this.DAOObject.OnInsert(func() error {
return SharedSysEventDAO.CreateEvent(NewServerChangeEvent())
})
this.DAOObject.OnDelete(func() error {
return SharedSysEventDAO.CreateEvent(NewServerChangeEvent())
})
}
2020-09-15 14:44:11 +08:00
// 启用条目
func (this *HTTPWebDAO) EnableHTTPWeb(id int64) error {
_, err := this.Query().
Pk(id).
Set("state", HTTPWebStateEnabled).
Update()
return err
}
// 禁用条目
func (this *HTTPWebDAO) DisableHTTPWeb(id int64) error {
_, err := this.Query().
Pk(id).
Set("state", HTTPWebStateDisabled).
Update()
return err
}
// 查找启用中的条目
func (this *HTTPWebDAO) FindEnabledHTTPWeb(id int64) (*HTTPWeb, error) {
result, err := this.Query().
Pk(id).
Attr("state", HTTPWebStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*HTTPWeb), err
}
// 组合配置
2020-09-16 09:09:21 +08:00
func (this *HTTPWebDAO) ComposeWebConfig(webId int64) (*serverconfigs.HTTPWebConfig, error) {
2020-09-15 14:44:11 +08:00
web, err := SharedHTTPWebDAO.FindEnabledHTTPWeb(webId)
if err != nil {
return nil, err
}
if web == nil {
return nil, nil
}
2020-09-20 16:28:07 +08:00
2020-09-16 09:09:21 +08:00
config := &serverconfigs.HTTPWebConfig{}
config.Id = webId
2020-09-15 14:44:11 +08:00
config.IsOn = web.IsOn == 1
2020-09-26 11:21:43 +08:00
// root
if IsNotNull(web.Root) {
rootConfig := &serverconfigs.HTTPRootConfig{}
err = json.Unmarshal([]byte(web.Root), rootConfig)
if err != nil {
return nil, err
}
config.Root = rootConfig
}
2020-09-16 09:09:21 +08:00
// gzip
2020-09-20 16:28:07 +08:00
if IsNotNull(web.Gzip) {
gzipRef := &serverconfigs.HTTPGzipRef{}
err = json.Unmarshal([]byte(web.Gzip), gzipRef)
if err != nil {
return nil, err
}
config.GzipRef = gzipRef
gzipConfig, err := SharedHTTPGzipDAO.ComposeGzipConfig(gzipRef.GzipId)
2020-09-16 09:09:21 +08:00
if err != nil {
return nil, err
}
config.Gzip = gzipConfig
}
2020-09-16 20:29:18 +08:00
// charset
2020-09-23 18:43:42 +08:00
if IsNotNull(web.Charset) {
charsetConfig := &serverconfigs.HTTPCharsetConfig{}
err = json.Unmarshal([]byte(web.Charset), charsetConfig)
if err != nil {
return nil, err
}
config.Charset = charsetConfig
}
2020-09-16 20:29:18 +08:00
// headers
2020-09-23 18:43:42 +08:00
if IsNotNull(web.RequestHeader) {
ref := &shared.HTTPHeaderPolicyRef{}
err = json.Unmarshal([]byte(web.RequestHeader), ref)
2020-09-16 20:29:18 +08:00
if err != nil {
return nil, err
}
2020-09-23 18:43:42 +08:00
config.RequestHeaderPolicyRef = ref
if ref.HeaderPolicyId > 0 {
headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(ref.HeaderPolicyId)
if err != nil {
return nil, err
}
if headerPolicy != nil {
config.RequestHeaderPolicy = headerPolicy
}
2020-09-16 20:29:18 +08:00
}
}
2020-09-23 18:43:42 +08:00
if IsNotNull(web.ResponseHeader) {
ref := &shared.HTTPHeaderPolicyRef{}
err = json.Unmarshal([]byte(web.ResponseHeader), ref)
2020-09-16 20:29:18 +08:00
if err != nil {
return nil, err
}
2020-09-23 18:43:42 +08:00
config.ResponseHeaderPolicyRef = ref
if ref.HeaderPolicyId > 0 {
headerPolicy, err := SharedHTTPHeaderPolicyDAO.ComposeHeaderPolicyConfig(ref.HeaderPolicyId)
if err != nil {
return nil, err
}
if headerPolicy != nil {
config.ResponseHeaderPolicy = headerPolicy
}
2020-09-16 20:29:18 +08:00
}
}
2020-09-16 09:09:21 +08:00
2020-09-17 10:16:00 +08:00
// shutdown
if IsNotNull(web.Shutdown) {
shutdownConfig := &serverconfigs.HTTPShutdownConfig{}
err = json.Unmarshal([]byte(web.Shutdown), shutdownConfig)
if err != nil {
return nil, err
}
config.Shutdown = shutdownConfig
}
// pages
if IsNotNull(web.Pages) {
pages := []*serverconfigs.HTTPPageConfig{}
err = json.Unmarshal([]byte(web.Pages), &pages)
if err != nil {
return nil, err
}
for index, page := range pages {
pageConfig, err := SharedHTTPPageDAO.ComposePageConfig(page.Id)
if err != nil {
return nil, err
}
pages[index] = pageConfig
}
if len(pages) > 0 {
config.Pages = pages
}
}
2020-09-20 11:56:30 +08:00
// 访问日志
if IsNotNull(web.AccessLog) {
2020-09-20 16:28:07 +08:00
accessLogConfig := &serverconfigs.HTTPAccessLogRef{}
2020-09-20 11:56:30 +08:00
err = json.Unmarshal([]byte(web.AccessLog), accessLogConfig)
if err != nil {
return nil, err
}
2020-09-20 16:28:07 +08:00
config.AccessLogRef = accessLogConfig
2020-09-20 11:56:30 +08:00
}
2020-09-20 14:48:41 +08:00
// 统计配置
if IsNotNull(web.Stat) {
2020-09-20 16:28:07 +08:00
statRef := &serverconfigs.HTTPStatRef{}
err = json.Unmarshal([]byte(web.Stat), statRef)
if err != nil {
return nil, err
}
config.StatRef = statRef
}
// 缓存配置
if IsNotNull(web.Cache) {
2020-10-04 20:38:12 +08:00
cacheConfig := &serverconfigs.HTTPCacheConfig{}
err = json.Unmarshal([]byte(web.Cache), &cacheConfig)
2020-09-20 14:48:41 +08:00
if err != nil {
return nil, err
}
2020-10-04 20:38:12 +08:00
config.Cache = cacheConfig
2020-12-17 17:36:20 +08:00
// 暂不支持自定义缓存策略设置,因为同一个集群下的服务需要集中管理
2020-09-20 14:48:41 +08:00
}
2020-09-20 20:12:47 +08:00
// 防火墙配置
if IsNotNull(web.Firewall) {
2020-10-06 21:02:15 +08:00
firewallRef := &firewallconfigs.HTTPFirewallRef{}
2020-09-20 20:12:47 +08:00
err = json.Unmarshal([]byte(web.Firewall), firewallRef)
if err != nil {
return nil, err
}
config.FirewallRef = firewallRef
2020-10-08 15:08:08 +08:00
2020-12-17 17:36:20 +08:00
// 暂不支持自定义防火墙策略设置,因为同一个集群下的服务需要集中管理
2020-09-20 20:12:47 +08:00
}
2020-09-21 19:51:56 +08:00
// 路径规则
if IsNotNull(web.Locations) {
refs := []*serverconfigs.HTTPLocationRef{}
err = json.Unmarshal([]byte(web.Locations), &refs)
if err != nil {
return nil, err
}
if len(refs) > 0 {
config.LocationRefs = refs
locations, err := SharedHTTPLocationDAO.ConvertLocationRefs(refs)
if err != nil {
return nil, err
}
config.Locations = locations
}
}
2020-09-23 18:43:42 +08:00
// 跳转
if IsNotNull(web.RedirectToHttps) {
redirectToHTTPSConfig := &serverconfigs.HTTPRedirectToHTTPSConfig{}
err = json.Unmarshal([]byte(web.RedirectToHttps), redirectToHTTPSConfig)
if err != nil {
return nil, err
}
config.RedirectToHttps = redirectToHTTPSConfig
}
2020-09-26 19:54:15 +08:00
// Websocket
if IsNotNull(web.Websocket) {
ref := &serverconfigs.HTTPWebsocketRef{}
err = json.Unmarshal([]byte(web.Websocket), ref)
if err != nil {
return nil, err
}
config.WebsocketRef = ref
if ref.WebsocketId > 0 {
websocketConfig, err := SharedHTTPWebsocketDAO.ComposeWebsocketConfig(ref.WebsocketId)
if err != nil {
return nil, err
}
if websocketConfig != nil {
config.Websocket = websocketConfig
}
}
}
2020-09-28 16:25:39 +08:00
// 重写规则
if IsNotNull(web.RewriteRules) {
refs := []*serverconfigs.HTTPRewriteRef{}
err = json.Unmarshal([]byte(web.RewriteRules), &refs)
if err != nil {
return nil, err
}
for _, ref := range refs {
rewriteRule, err := SharedHTTPRewriteRuleDAO.ComposeRewriteRule(ref.RewriteRuleId)
if err != nil {
return nil, err
}
if rewriteRule != nil {
config.RewriteRefs = append(config.RewriteRefs, ref)
config.RewriteRules = append(config.RewriteRules, rewriteRule)
}
}
}
2020-09-15 14:44:11 +08:00
return config, nil
}
// 创建Web配置
2020-09-26 11:21:43 +08:00
func (this *HTTPWebDAO) CreateWeb(rootJSON []byte) (int64, error) {
2020-09-15 14:44:11 +08:00
op := NewHTTPWebOperator()
op.State = HTTPWebStateEnabled
2020-09-26 19:54:15 +08:00
op.Root = JSONBytes(rootJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-15 14:44:11 +08:00
if err != nil {
return 0, err
}
return types.Int64(op.Id), nil
}
// 修改Web配置
2020-09-26 11:21:43 +08:00
func (this *HTTPWebDAO) UpdateWeb(webId int64, rootJSON []byte) error {
2020-09-15 14:44:11 +08:00
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
2020-09-26 19:54:15 +08:00
op.Root = JSONBytes(rootJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-16 09:09:21 +08:00
}
2020-09-15 14:44:11 +08:00
2020-09-16 09:09:21 +08:00
// 修改Gzip配置
2020-09-20 16:28:07 +08:00
func (this *HTTPWebDAO) UpdateWebGzip(webId int64, gzipJSON []byte) error {
2020-09-16 09:09:21 +08:00
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
2020-09-26 19:54:15 +08:00
op.Gzip = JSONBytes(gzipJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-16 09:09:21 +08:00
}
2020-09-16 20:29:18 +08:00
// 修改字符编码
2020-09-23 18:43:42 +08:00
func (this *HTTPWebDAO) UpdateWebCharset(webId int64, charsetJSON []byte) error {
2020-09-16 20:29:18 +08:00
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
2020-09-26 19:54:15 +08:00
op.Charset = JSONBytes(charsetJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-16 20:29:18 +08:00
}
// 更改请求Header策略
2020-09-23 18:43:42 +08:00
func (this *HTTPWebDAO) UpdateWebRequestHeaderPolicy(webId int64, headerPolicyJSON []byte) error {
2020-09-16 20:29:18 +08:00
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
2020-09-23 18:43:42 +08:00
op.RequestHeader = JSONBytes(headerPolicyJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-16 20:29:18 +08:00
}
// 更改响应Header策略
2020-09-23 18:43:42 +08:00
func (this *HTTPWebDAO) UpdateWebResponseHeaderPolicy(webId int64, headerPolicyJSON []byte) error {
2020-09-16 20:29:18 +08:00
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
2020-09-23 18:43:42 +08:00
op.ResponseHeader = JSONBytes(headerPolicyJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-16 20:29:18 +08:00
}
2020-09-17 10:16:00 +08:00
// 更改特殊页面配置
func (this *HTTPWebDAO) UpdateWebPages(webId int64, pagesJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.Pages = JSONBytes(pagesJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-17 10:16:00 +08:00
}
// 更改Shutdown配置
func (this *HTTPWebDAO) UpdateWebShutdown(webId int64, shutdownJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.Shutdown = JSONBytes(shutdownJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-17 10:16:00 +08:00
}
2020-09-20 11:56:30 +08:00
// 更改访问日志策略
func (this *HTTPWebDAO) UpdateWebAccessLogConfig(webId int64, accessLogJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.AccessLog = JSONBytes(accessLogJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-20 11:56:30 +08:00
}
2020-09-20 14:48:41 +08:00
// 更改统计配置
func (this *HTTPWebDAO) UpdateWebStat(webId int64, statJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.Stat = JSONBytes(statJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-20 14:48:41 +08:00
}
2020-09-20 16:28:07 +08:00
// 更改缓存配置
func (this *HTTPWebDAO) UpdateWebCache(webId int64, cacheJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.Cache = JSONBytes(cacheJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-20 16:28:07 +08:00
}
2020-09-20 20:12:47 +08:00
// 更改防火墙配置
func (this *HTTPWebDAO) UpdateWebFirewall(webId int64, firewallJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.Firewall = JSONBytes(firewallJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-20 20:12:47 +08:00
}
2020-09-21 19:51:56 +08:00
// 更改路径规则配置
func (this *HTTPWebDAO) UpdateWebLocations(webId int64, locationsJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.Locations = JSONBytes(locationsJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-21 19:51:56 +08:00
}
2020-09-23 18:43:42 +08:00
// 更改跳转到HTTPS设置
func (this *HTTPWebDAO) UpdateWebRedirectToHTTPS(webId int64, redirectToHTTPSJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.RedirectToHttps = JSONBytes(redirectToHTTPSJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 08:06:40 +08:00
return err
2020-09-15 14:44:11 +08:00
}
2020-09-26 19:54:15 +08:00
// 修改Websocket设置
func (this *HTTPWebDAO) UpdateWebsocket(webId int64, websocketJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.Websocket = JSONBytes(websocketJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-26 19:54:15 +08:00
return err
}
2020-09-28 16:25:39 +08:00
// 修改重写规则设置
func (this *HTTPWebDAO) UpdateWebRewriteRules(webId int64, rewriteRulesJSON []byte) error {
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
op.Id = webId
op.RewriteRules = JSONBytes(rewriteRulesJSON)
2020-12-09 20:44:05 +08:00
err := this.Save(op)
2020-09-28 16:25:39 +08:00
return err
}
2020-10-02 17:22:32 +08:00
// 根据缓存策略ID查找所有的WebId
func (this *HTTPWebDAO) FindAllWebIdsWithCachePolicyId(cachePolicyId int64) ([]int64, error) {
ones, err := this.Query().
State(HTTPWebStateEnabled).
ResultPk().
2020-10-06 21:02:15 +08:00
Where(`JSON_CONTAINS(cache, '{"cachePolicyId": ` + strconv.FormatInt(cachePolicyId, 10) + ` }', '$.cacheRefs')`).
Reuse(false). // 由于我们在JSON_CONTAINS()直接使用了变量,所以不能重用
FindAll()
if err != nil {
return nil, err
}
result := []int64{}
for _, one := range ones {
webId := int64(one.(*HTTPWeb).Id)
// 判断是否为Location
for {
locationId, err := SharedHTTPLocationDAO.FindEnabledLocationIdWithWebId(webId)
if err != nil {
return nil, err
}
// 如果非Location
if locationId == 0 {
2020-10-20 20:18:06 +08:00
if !lists.ContainsInt64(result, webId) {
2020-10-06 21:02:15 +08:00
result = append(result, webId)
}
break
}
// 查找包含此Location的Web
// TODO 需要支持嵌套的Location查询
webId, err = this.FindEnabledWebIdWithLocationId(locationId)
if err != nil {
return nil, err
}
if webId == 0 {
break
}
}
}
return result, nil
}
// 根据防火墙策略ID查找所有的WebId
func (this *HTTPWebDAO) FindAllWebIdsWithHTTPFirewallPolicyId(firewallPolicyId int64) ([]int64, error) {
ones, err := this.Query().
State(HTTPWebStateEnabled).
ResultPk().
Where(`JSON_CONTAINS(firewall, '{"isOn": true, "firewallPolicyId": ` + strconv.FormatInt(firewallPolicyId, 10) + ` }')`).
2020-10-02 17:22:32 +08:00
Reuse(false). // 由于我们在JSON_CONTAINS()直接使用了变量,所以不能重用
FindAll()
if err != nil {
return nil, err
}
result := []int64{}
for _, one := range ones {
webId := int64(one.(*HTTPWeb).Id)
// 判断是否为Location
for {
locationId, err := SharedHTTPLocationDAO.FindEnabledLocationIdWithWebId(webId)
if err != nil {
return nil, err
}
// 如果非Location
if locationId == 0 {
2020-10-20 20:18:06 +08:00
if !lists.ContainsInt64(result, webId) {
2020-10-02 17:22:32 +08:00
result = append(result, webId)
}
break
}
// 查找包含此Location的Web
// TODO 需要支持嵌套的Location查询
webId, err = this.FindEnabledWebIdWithLocationId(locationId)
if err != nil {
return nil, err
}
if webId == 0 {
break
}
}
}
return result, nil
}
// 查找包含某个Location的Web
func (this *HTTPWebDAO) FindEnabledWebIdWithLocationId(locationId int64) (webId int64, err error) {
return this.Query().
State(HTTPWebStateEnabled).
ResultPk().
Where(`JSON_CONTAINS(locations, '{"locationId": ` + strconv.FormatInt(locationId, 10) + ` }')`).
Reuse(false). // 由于我们在JSON_CONTAINS()直接使用了变量,所以不能重用
FindInt64Col(0)
}