Files
EdgeAPI/internal/setup/sql_upgrade.go

586 lines
13 KiB
Go
Raw Normal View History

package setup
import (
2021-07-14 22:46:23 +08:00
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/acme"
2021-01-20 14:19:29 +08:00
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
2021-02-02 19:29:36 +08:00
"github.com/TeaOSLab/EdgeAPI/internal/utils"
2021-08-06 14:22:17 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
2021-07-14 22:46:23 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
2021-08-06 14:22:17 +08:00
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
"github.com/iwind/TeaGo/dbs"
2021-01-20 14:19:29 +08:00
"github.com/iwind/TeaGo/lists"
2021-07-14 22:46:23 +08:00
"github.com/iwind/TeaGo/maps"
2020-12-14 21:25:11 +08:00
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types"
stringutil "github.com/iwind/TeaGo/utils/string"
2021-08-09 13:57:58 +08:00
"regexp"
)
type upgradeVersion struct {
version string
f func(db *dbs.DB) error
}
var upgradeFuncs = []*upgradeVersion{
{
"0.0.3", upgradeV0_0_3,
},
{
"0.0.5", upgradeV0_0_5,
},
2020-12-14 21:25:11 +08:00
{
"0.0.6", upgradeV0_0_6,
},
2021-01-20 14:19:29 +08:00
{
"0.0.9", upgradeV0_0_9,
},
2021-02-02 19:29:36 +08:00
{
"0.0.10", upgradeV0_0_10,
},
2021-07-11 18:05:57 +08:00
{
"0.2.5", upgradeV0_2_5,
},
2021-08-06 14:22:17 +08:00
{
2021-08-09 13:57:58 +08:00
"0.2.8.1", upgradeV0_2_8_1,
2021-08-06 14:22:17 +08:00
},
{
"0.3.0", upgradeV0_3_0,
},
2021-09-08 17:31:18 +08:00
{
"0.3.1", upgradeV0_3_1,
},
{
"0.3.2", upgradeV0_3_2,
},
{
"0.3.3", upgradeV0_3_3,
},
2021-12-06 19:27:11 +08:00
{
"0.3.7", upgradeV0_3_7,
},
2022-01-10 20:07:26 +08:00
{
"0.4.0", upgradeV0_4_0,
},
2022-01-23 19:16:52 +08:00
{
"0.4.1", upgradeV0_4_1,
},
}
2021-07-11 18:05:57 +08:00
// UpgradeSQLData 升级SQL数据
func UpgradeSQLData(db *dbs.DB) error {
version, err := db.FindCol(0, "SELECT version FROM edgeVersions")
if err != nil {
return err
}
versionString := types.String(version)
if len(versionString) > 0 {
for _, f := range upgradeFuncs {
if stringutil.VersionCompare(versionString, f.version) >= 0 {
continue
}
err = f.f(db)
if err != nil {
return err
}
}
}
return nil
}
// v0.0.3
func upgradeV0_0_3(db *dbs.DB) error {
// 获取第一个管理员
adminIdCol, err := db.FindCol(0, "SELECT id FROM edgeAdmins ORDER BY id ASC LIMIT 1")
if err != nil {
return err
}
adminId := types.Int64(adminIdCol)
if adminId <= 0 {
return errors.New("'edgeAdmins' table should not be empty")
}
// 升级edgeDNSProviders
_, err = db.Exec("UPDATE edgeDNSProviders SET adminId=? WHERE adminId=0 AND userId=0", adminId)
if err != nil {
return err
}
// 升级edgeDNSDomains
_, err = db.Exec("UPDATE edgeDNSDomains SET adminId=? WHERE adminId=0 AND userId=0", adminId)
if err != nil {
return err
}
// 升级edgeSSLCerts
_, err = db.Exec("UPDATE edgeSSLCerts SET adminId=? WHERE adminId=0 AND userId=0", adminId)
if err != nil {
return err
}
// 升级edgeNodeClusters
_, err = db.Exec("UPDATE edgeNodeClusters SET adminId=? WHERE adminId=0 AND userId=0", adminId)
if err != nil {
return err
}
// 升级edgeNodes
_, err = db.Exec("UPDATE edgeNodes SET adminId=? WHERE adminId=0 AND userId=0", adminId)
if err != nil {
return err
}
2020-11-27 10:02:46 +08:00
// 升级edgeNodeGrants
_, err = db.Exec("UPDATE edgeNodeGrants SET adminId=? WHERE adminId=0", adminId)
if err != nil {
return err
}
return nil
}
2020-12-14 21:25:11 +08:00
// v0.0.5
func upgradeV0_0_5(db *dbs.DB) error {
// 升级edgeACMETasks
_, err := db.Exec("UPDATE edgeACMETasks SET authType=? WHERE authType IS NULL OR LENGTH(authType)=0", acme.AuthTypeDNS)
if err != nil {
return err
}
return nil
}
2020-12-14 21:25:11 +08:00
// v0.0.6
func upgradeV0_0_6(db *dbs.DB) error {
stmt, err := db.Prepare("SELECT COUNT(*) FROM edgeAPITokens WHERE role='user'")
if err != nil {
return err
}
defer func() {
_ = stmt.Close()
}()
col, err := stmt.FindCol(0)
if err != nil {
return err
}
count := types.Int(col)
if count > 0 {
return nil
}
nodeId := rands.HexString(32)
secret := rands.String(32)
_, err = db.Exec("INSERT INTO edgeAPITokens (nodeId, secret, role) VALUES (?, ?, ?)", nodeId, secret, "user")
if err != nil {
return err
}
return nil
}
2021-01-20 14:19:29 +08:00
// v0.0.9
func upgradeV0_0_9(db *dbs.DB) error {
// firewall policies
var tx *dbs.Tx
dbs.NotifyReady()
policies, err := models.NewHTTPFirewallPolicyDAO().FindAllEnabledFirewallPolicies(tx)
if err != nil {
return err
}
for _, policy := range policies {
if policy.ServerId > 0 {
continue
}
policyId := int64(policy.Id)
webIds, err := models.NewHTTPWebDAO().FindAllWebIdsWithHTTPFirewallPolicyId(tx, policyId)
if err != nil {
return err
}
serverIds := []int64{}
for _, webId := range webIds {
serverId, err := models.NewServerDAO().FindEnabledServerIdWithWebId(tx, webId)
if err != nil {
return err
}
if serverId > 0 && !lists.ContainsInt64(serverIds, serverId) {
serverIds = append(serverIds, serverId)
}
}
if len(serverIds) == 1 {
err = models.NewHTTPFirewallPolicyDAO().UpdateFirewallPolicyServerId(tx, policyId, serverIds[0])
if err != nil {
return err
}
}
}
return nil
}
2021-02-02 19:29:36 +08:00
// v0.0.10
func upgradeV0_0_10(db *dbs.DB) error {
// IP Item列表转换
ones, _, err := db.FindOnes("SELECT * FROM edgeIPItems ORDER BY id ASC")
if err != nil {
return err
}
for _, one := range ones {
ipFromLong := utils.IP2Long(one.GetString("ipFrom"))
ipToLong := utils.IP2Long(one.GetString("ipTo"))
_, err = db.Exec("UPDATE edgeIPItems SET ipFromLong=?, ipToLong=? WHERE id=?", ipFromLong, ipToLong, one.GetInt64("id"))
if err != nil {
return err
}
}
return nil
}
2021-07-11 18:05:57 +08:00
// v0.2.5
func upgradeV0_2_5(db *dbs.DB) error {
2021-07-14 22:46:23 +08:00
// 更新用户
_, err := db.Exec("UPDATE edgeUsers SET day=FROM_UNIXTIME(createdAt,'%Y%m%d') WHERE day IS NULL OR LENGTH(day)=0")
2021-07-11 18:05:57 +08:00
if err != nil {
return err
}
2021-07-14 22:46:23 +08:00
// 更新防火墙规则
ones, _, err := db.FindOnes("SELECT id, actions, action, actionOptions FROM edgeHTTPFirewallRuleSets WHERE actions IS NULL OR LENGTH(actions)=0")
if err != nil {
return err
}
for _, one := range ones {
oneId := one.GetInt64("id")
action := one.GetString("action")
options := one.GetString("actionOptions")
var optionsMap = maps.Map{}
if len(options) > 0 {
_ = json.Unmarshal([]byte(options), &optionsMap)
}
var actions = []*firewallconfigs.HTTPFirewallActionConfig{
{
Code: action,
Options: optionsMap,
},
}
actionsJSON, err := json.Marshal(actions)
if err != nil {
return err
}
_, err = db.Exec("UPDATE edgeHTTPFirewallRuleSets SET actions=? WHERE id=?", string(actionsJSON), oneId)
if err != nil {
return err
}
}
2021-07-11 18:05:57 +08:00
return nil
}
2021-08-06 14:22:17 +08:00
2021-08-09 13:57:58 +08:00
// v0.2.8.1
func upgradeV0_2_8_1(db *dbs.DB) error {
// 访问日志设置
2021-08-06 14:22:17 +08:00
{
one, err := db.FindOne("SELECT id FROM edgeSysSettings WHERE code=? LIMIT 1", systemconfigs.SettingCodeNSAccessLogSetting)
if err != nil {
return err
}
if len(one) == 0 {
ref := &dnsconfigs.NSAccessLogRef{
IsPrior: false,
IsOn: true,
LogMissingDomains: false,
}
refJSON, err := json.Marshal(ref)
if err != nil {
return err
}
_, err = db.Exec("INSERT edgeSysSettings (code, value) VALUES (?, ?)", systemconfigs.SettingCodeNSAccessLogSetting, refJSON)
if err != nil {
return err
}
}
}
2021-08-09 13:57:58 +08:00
// 升级EdgeDNS线路
ones, _, err := db.FindOnes("SELECT id, dnsRoutes FROM edgeNodes WHERE dnsRoutes IS NOT NULL")
if err != nil {
return err
}
for _, one := range ones {
var nodeId = one.GetInt64("id")
var dnsRoutes = one.GetString("dnsRoutes")
if len(dnsRoutes) == 0 {
continue
}
var m = map[string][]string{}
err = json.Unmarshal([]byte(dnsRoutes), &m)
if err != nil {
continue
}
var isChanged = false
var reg = regexp.MustCompile(`^\d+$`)
for k, routes := range m {
for index, route := range routes {
if reg.MatchString(route) {
route = "id:" + route
isChanged = true
}
routes[index] = route
}
m[k] = routes
}
if isChanged {
mJSON, err := json.Marshal(m)
if err != nil {
return err
}
_, err = db.Exec("UPDATE edgeNodes SET dnsRoutes=? WHERE id=? LIMIT 1", string(mJSON), nodeId)
if err != nil {
return err
}
}
}
2021-08-06 14:22:17 +08:00
return nil
}
// v0.3.0
func upgradeV0_3_0(db *dbs.DB) error {
// 升级健康检查
ones, _, err := db.FindOnes("SELECT id,healthCheck FROM edgeNodeClusters WHERE state=1")
if err != nil {
return err
}
for _, one := range ones {
var clusterId = one.GetInt64("id")
var healthCheck = one.GetString("healthCheck")
if len(healthCheck) == 0 {
continue
}
var config = &serverconfigs.HealthCheckConfig{}
err = json.Unmarshal([]byte(healthCheck), config)
if err != nil {
continue
}
if config.CountDown <= 1 {
config.CountDown = 3
configJSON, err := json.Marshal(config)
if err != nil {
continue
}
_, err = db.Exec("UPDATE edgeNodeClusters SET healthCheck=? WHERE id=?", string(configJSON), clusterId)
if err != nil {
return err
}
}
}
return nil
}
2021-09-08 17:31:18 +08:00
// v0.3.1
func upgradeV0_3_1(db *dbs.DB) error {
2021-09-12 20:21:42 +08:00
// 清空域名统计,已使用分表代替
// 因为可能有权限问题,所以我们忽略错误
2021-09-08 17:31:18 +08:00
_, _ = db.Exec("TRUNCATE table edgeServerDomainHourlyStats")
// 升级APIToken
ones, _, err := db.FindOnes("SELECT uniqueId,secret FROM edgeNodeClusters")
if err != nil {
return err
}
for _, one := range ones {
var uniqueId = one.GetString("uniqueId")
var secret = one.GetString("secret")
tokenOne, err := db.FindOne("SELECT id FROM edgeAPITokens WHERE nodeId=? LIMIT 1", uniqueId)
if err != nil {
return err
}
if len(tokenOne) == 0 {
_, err = db.Exec("INSERT INTO edgeAPITokens (nodeId, secret, role, state) VALUES (?, ?, 'cluster', 1)", uniqueId, secret)
if err != nil {
return err
}
}
}
2021-09-08 17:31:18 +08:00
return nil
}
// v0.3.2
func upgradeV0_3_2(db *dbs.DB) error {
// gzip => compression
type HTTPGzipRef struct {
IsPrior bool `yaml:"isPrior" json:"isPrior"` // 是否覆盖
IsOn bool `yaml:"isOn" json:"isOn"` // 是否开启
GzipId int64 `yaml:"gzipId" json:"gzipId"` // 使用的配置ID
}
2021-10-29 14:02:40 +08:00
webOnes, _, err := db.FindOnes("SELECT id, gzip FROM edgeHTTPWebs WHERE gzip IS NOT NULL AND compression IS NULL")
if err != nil {
return err
}
for _, webOne := range webOnes {
var gzipRef = &HTTPGzipRef{}
err = json.Unmarshal([]byte(webOne.GetString("gzip")), gzipRef)
if err != nil {
continue
}
if gzipRef == nil || gzipRef.GzipId <= 0 {
continue
}
var webId = webOne.GetInt("id")
var compressionConfig = &serverconfigs.HTTPCompressionConfig{
UseDefaultTypes: true,
}
compressionConfig.IsPrior = gzipRef.IsPrior
compressionConfig.IsOn = gzipRef.IsOn
gzipOne, err := db.FindOne("SELECT * FROM edgeHTTPGzips WHERE id=?", gzipRef.GzipId)
if err != nil {
return err
}
if len(gzipOne) == 0 {
continue
}
level := gzipOne.GetInt("level")
if level <= 0 {
continue
}
if level > 0 && level <= 10 {
compressionConfig.Level = types.Int8(level)
} else if level > 10 {
compressionConfig.Level = 10
}
var minLengthBytes = []byte(gzipOne.GetString("minLength"))
if len(minLengthBytes) > 0 {
var sizeCapacity = &shared.SizeCapacity{}
err = json.Unmarshal(minLengthBytes, sizeCapacity)
if err != nil {
continue
}
if sizeCapacity != nil {
compressionConfig.MinLength = sizeCapacity
}
}
var maxLengthBytes = []byte(gzipOne.GetString("maxLength"))
if len(maxLengthBytes) > 0 {
var sizeCapacity = &shared.SizeCapacity{}
err = json.Unmarshal(maxLengthBytes, sizeCapacity)
if err != nil {
continue
}
if sizeCapacity != nil {
compressionConfig.MaxLength = sizeCapacity
}
}
var condsBytes = []byte(gzipOne.GetString("conds"))
if len(condsBytes) > 0 {
var conds = &shared.HTTPRequestCondsConfig{}
err = json.Unmarshal(condsBytes, conds)
if err != nil {
continue
}
if conds != nil {
compressionConfig.Conds = conds
}
}
configJSON, err := json.Marshal(compressionConfig)
if err != nil {
return err
}
_, err = db.Exec("UPDATE edgeHTTPWebs SET compression=? WHERE id=?", string(configJSON), webId)
if err != nil {
return err
}
}
2021-10-10 16:29:50 +08:00
// 更新服务端口
var serverDAO = models.NewServerDAO()
ones, err := serverDAO.Query(nil).
ResultPk().
FindAll()
if err != nil {
return err
}
for _, one := range ones {
var serverId = int64(one.(*models.Server).Id)
err = serverDAO.NotifyServerPortsUpdate(nil, serverId)
if err != nil {
return err
}
}
return nil
}
// v0.3.3
func upgradeV0_3_3(db *dbs.DB) error {
// 升级CC请求数Code
_, err := db.Exec("UPDATE edgeHTTPFirewallRuleSets SET code='8002' WHERE name='CC请求数' AND code='8001'")
if err != nil {
return err
}
// 清除节点
// 删除7天以前的info日志
err = models.NewNodeLogDAO().DeleteExpiredLogsWithLevel(nil, "info", 7)
if err != nil {
return err
}
return nil
}
2021-12-06 19:27:11 +08:00
// v0.3.7
func upgradeV0_3_7(db *dbs.DB) error {
// 修改所有edgeNodeGrants中的su为0
_, err := db.Exec("UPDATE edgeNodeGrants SET su=0 WHERE su=1")
if err != nil {
return err
}
// WAF预置分组
_, err = db.Exec("UPDATE edgeHTTPFirewallRuleGroups SET isTemplate=1 WHERE LENGTH(code)>0")
if err != nil {
return err
}
2021-12-06 19:27:11 +08:00
return nil
}
2022-01-10 20:07:26 +08:00
// v0.4.0
func upgradeV0_4_0(db *dbs.DB) error {
// 升级SYN Flood配置
synFloodJSON, err := json.Marshal(firewallconfigs.DefaultSYNFloodConfig())
if err == nil {
_, err := db.Exec("UPDATE edgeHTTPFirewallPolicies SET synFlood=? WHERE synFlood IS NULL AND state=1", string(synFloodJSON))
if err != nil {
return err
}
}
return nil
}
2022-01-23 19:16:52 +08:00
// v0.4.1
func upgradeV0_4_1(db *dbs.DB) error {
// 升级 servers.lastUserPlanId
_, err := db.Exec("UPDATE edgeServers SET lastUserPlanId=userPlanId WHERE userPlanId>0")
if err != nil {
return err
}
return nil
}