// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn . //go:build plus package setup import ( "encoding/json" "fmt" "github.com/TeaOSLab/EdgeAPI/internal/db/models" "github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/userconfigs" "github.com/iwind/TeaGo/dbs" "github.com/iwind/TeaGo/types" timeutil "github.com/iwind/TeaGo/utils/time" "regexp" "strings" "time" ) // v0.2.8.1 func upgradeV0_2_8_1(db *dbs.DB) error { // 访问日志设置 { one, err := db.FindOne("SELECT id FROM edgeSysSettings WHERE code=? LIMIT 1", systemconfigs.SettingCodeNSAccessLogSetting) if err != nil { return err } if len(one) == 0 { var 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 } } } // 升级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 } } } return nil } // v0.4.9 func upgradeV0_4_9(db *dbs.DB) error { // 升级用户UI配置 { one, err := db.FindOne("SELECT value FROM edgeSysSettings WHERE code=?", systemconfigs.SettingCodeUserUIConfig) if err != nil { return err } if one != nil { var valueJSON = one.GetBytes("value") if len(valueJSON) > 0 { var config = &systemconfigs.UserUIConfig{} err = json.Unmarshal(valueJSON, config) if err == nil { config.ShowTrafficCharts = true config.ShowBandwidthCharts = true config.BandwidthUnit = systemconfigs.BandwidthUnitBit configJSON, err := json.Marshal(config) if err != nil { return fmt.Errorf("encode UserUIConfig failed: %w", err) } else { _, err := db.Exec("UPDATE edgeSysSettings SET value=? WHERE code=?", configJSON, systemconfigs.SettingCodeUserUIConfig) if err != nil { return err } } } } } } // 升级管理配置 { one, err := db.FindOne("SELECT value FROM edgeSysSettings WHERE code=?", systemconfigs.SettingCodeAdminSecurityConfig) if err != nil { return err } if one != nil { var valueJSON = one.GetBytes("value") if len(valueJSON) > 0 { var config = &systemconfigs.SecurityConfig{} err = json.Unmarshal(valueJSON, config) if err == nil { config.DenySearchEngines = true config.DenySpiders = true configJSON, err := json.Marshal(config) if err != nil { return fmt.Errorf("encode SecurityConfig failed: %w", err) } else { _, err := db.Exec("UPDATE edgeSysSettings SET value=? WHERE code=?", configJSON, systemconfigs.SettingCodeAdminSecurityConfig) if err != nil { return err } } } } } } return nil } // v0.5.3 func upgradeV0_5_3(db *dbs.DB) error { // 升级ns domains中的status字段 { _, err := db.Exec("UPDATE edgeNSDomains SET status='" + dnsconfigs.NSDomainStatusVerified + "'") if err != nil { return err } } // 升级集群服务配置 { type oldGlobalConfig struct { // HTTP & HTTPS相关配置 HTTPAll struct { MatchDomainStrictly bool `yaml:"matchDomainStrictly" json:"matchDomainStrictly"` // 是否严格匹配域名 AllowMismatchDomains []string `yaml:"allowMismatchDomains" json:"allowMismatchDomains"` // 允许的不匹配的域名 DefaultDomain string `yaml:"defaultDomain" json:"defaultDomain"` // 默认的域名 DomainMismatchAction *serverconfigs.DomainMismatchAction `yaml:"domainMismatchAction" json:"domainMismatchAction"` // 不匹配时采取的动作 } `yaml:"httpAll" json:"httpAll"` } value, err := db.FindCol(0, "SELECT value FROM edgeSysSettings WHERE code='serverGlobalConfig'") if err != nil { return err } if value != nil { var valueJSON = []byte(types.String(value)) var oldConfig = &oldGlobalConfig{} err = json.Unmarshal(valueJSON, oldConfig) if err == nil { var newConfig = &serverconfigs.GlobalServerConfig{} newConfig.HTTPAll.MatchDomainStrictly = oldConfig.HTTPAll.MatchDomainStrictly newConfig.HTTPAll.AllowMismatchDomains = oldConfig.HTTPAll.AllowMismatchDomains newConfig.HTTPAll.DefaultDomain = oldConfig.HTTPAll.DefaultDomain if oldConfig.HTTPAll.DomainMismatchAction != nil { newConfig.HTTPAll.DomainMismatchAction = oldConfig.HTTPAll.DomainMismatchAction } newConfig.HTTPAll.AllowNodeIP = true newConfig.Log.RecordServerError = false newConfigJSON, err := json.Marshal(newConfig) if err == nil { _, err = db.Exec("UPDATE edgeNodeClusters SET globalServerConfig=?", newConfigJSON) if err != nil { return err } } } } } return nil } func upgradeV0_5_6(db *dbs.DB) error { // 升级PriceConfig enablePlans err := func() error { countPlans, err := db.FindCol(0, "SELECT COUNT(*) FROM edgePlans WHERE state=1") if err != nil { return err } var countPlansInt = types.Int64(countPlans) if countPlansInt > 0 { countUserPlans, err := db.FindCol(0, "SELECT COUNT(*) FROM edgeUserPlans WHERE state=1") if err != nil { return err } var countUserPlansInt = types.Int64(countUserPlans) if countUserPlansInt > 0 { countServers, err := db.FindCol(0, "SELECT COUNT(*) FROM edgeServers WHERE state=1 AND userPlanId>0") if err != nil { return err } var countServersInt = types.Int64(countServers) if countServersInt > 0 { var config = userconfigs.DefaultUserPriceConfig() configValue, err := db.FindCol(0, "SELECT value FROM edgeSysSettings WHERE code='"+systemconfigs.SettingCodeUserPriceConfig+"'") if err != nil { return err } var configValueString = types.String(configValue) if len(configValueString) > 0 { err = json.Unmarshal([]byte(configValueString), config) if err == nil && config.IsOn { // 如果已经设置了,则不重复设置 return nil } } if err == nil { config.IsOn = true config.EnablePlans = true configJSON, err := json.Marshal(config) if err != nil { return fmt.Errorf("encode price config failed: %w", err) } if len(configValueString) > 0 { // update _, err = db.Exec("UPDATE edgeSysSettings SET value=? WHERE code=?", configJSON, systemconfigs.SettingCodeUserPriceConfig) } else { // insert _, err = db.Exec("INSERT edgeSysSettings (code, value) VALUES (?, ?)", systemconfigs.SettingCodeUserPriceConfig, configJSON) } if err != nil { return err } } } } } return nil }() if err != nil { return err } // 修复默认集群的DNS设置 { var id = 1 clusterMap, err := db.FindOne("SELECT dns FROM edgeNodeClusters WHERE id=? AND state=1", id) if err != nil { return err } if len(clusterMap) > 0 { var dnsString = clusterMap.GetString("dns") if len(dnsString) > 0 && dnsString != "null" { var dnsData = []byte(dnsString) var dnsConfig = &dnsconfigs.ClusterDNSConfig{ CNAMEAsDomain: true, IncludingLnNodes: true, } err = json.Unmarshal(dnsData, dnsConfig) if err == nil && !dnsConfig.NodesAutoSync && !dnsConfig.ServersAutoSync { dnsConfig.NodesAutoSync = true dnsConfig.ServersAutoSync = true dnsConfigJSON, err := json.Marshal(dnsConfig) if err != nil { return err } _, err = db.Exec("UPDATE edgeNodeClusters SET dns=? WHERE id=?", dnsConfigJSON, id) if err != nil { return err } } } } } return nil } // v0.5.8 func upgradeV0_5_8(db *dbs.DB) error { // node task versions { _, err := db.Exec("UPDATE edgeNodeTasks SET version=0 WHERE LENGTH(version)=19") if err != nil { return err } } // ns mx records { _, err := db.Exec("UPDATE edgeNSRecords SET mxPriority=10 WHERE type='MX' AND mxPriority=0") if err != nil { return err } } // 删除操作系统和浏览器相关统计 // 只删除当前月,避免因为数据过多阻塞 { _, err := db.Exec("DELETE FROM edgeServerClientSystemMonthlyStats WHERE month=?", timeutil.Format("Ym")) if err != nil { return err } } { _, err := db.Exec("DELETE FROM edgeServerClientBrowserMonthlyStats WHERE month=?", timeutil.Format("Ym")) if err != nil { return err } } // 修复默认黑白名单不是全局的问题 { _, err := db.Exec("UPDATE edgeIPLists SET isGlobal=1 WHERE id IN (1, 2)") if err != nil { return err } } return nil } // v1.2.9 func upgradeV1_2_9(db *dbs.DB) error { // 升级WAF规则 { _, err := db.Exec("UPDATE edgeHTTPFirewallRules SET value=? WHERE value=? AND param='${userAgent}'", "python|pycurl|http-client|httpclient|apachebench|nethttp|http_request|java|perl|ruby|scrapy|php\\b|rust", "python|pycurl|http-client|httpclient|apachebench|nethttp|http_request|java|perl|ruby|scrapy|php|rust") if err != nil { return err } } // 升级套餐网站数限制 { _, err := db.Exec("UPDATE edgePlans SET totalServers=1 WHERE totalServers=0") if err != nil { return err } } // 升级网站流量限制状态 { _, err := db.Exec("UPDATE edgeServers SET trafficLimitStatus=NULL WHERE trafficLimitStatus IS NOT NULL") if err != nil { return err } } // 升级套餐按日/按月统计数据 { // 检查是否已升级 countUserPlanStatsValue, err := db.FindCol(0, "SELECT COUNT(*) FROM edgeUserPlanStats") if err != nil { return err } var countUserPlanStats = 0 if countUserPlanStatsValue != nil { countUserPlanStats = types.Int(countUserPlanStatsValue) } if countUserPlanStats == 0 { var upgradeFunc = func(userPlanId int64, serverId int64, month string) error { var bandwidthTable = "edgeServerBandwidthStats_" + types.String(serverId%models.ServerBandwidthStatTablePartitions) sumMap, err := db.FindOne("SELECT SUM(totalBytes) AS totalBytes,SUM(countRequests) AS countRequests FROM "+bandwidthTable+" WHERE serverId=? AND day BETWEEN ? AND ?", serverId, month+"01", month+"31") if err != nil { return err } if sumMap != nil && len(sumMap) >= 2 { var totalBytes = sumMap.GetInt64("totalBytes") var countRequests = sumMap.GetInt64("countRequests") if totalBytes > 0 || countRequests > 0 { _, err = db.Exec("INSERT INTO edgeUserPlanStats (userPlanId, date, dateType, trafficBytes, countRequests) VALUES (?, ?, ?, ?, ?)", userPlanId, month, "month", totalBytes, countRequests) if err != nil { var errMessage = strings.ToLower(err.Error()) if !strings.Contains(errMessage, "duplicate") && !strings.Contains(errMessage, "1062") { return err } err = nil } // daily for i := 1; i <= 31; i++ { var day = month + fmt.Sprintf("%02d", i) dailySumMap, err := db.FindOne("SELECT SUM(totalBytes) AS totalBytes,SUM(countRequests) AS countRequests FROM "+bandwidthTable+" WHERE serverId=? AND day=?", serverId, day) if err != nil { return err } var dailyTotalBytes = dailySumMap.GetInt64("totalBytes") var dailyCountRequests = dailySumMap.GetInt64("countRequests") if dailyTotalBytes > 0 || dailyCountRequests > 0 { _, err = db.Exec("INSERT INTO edgeUserPlanStats (userPlanId, date, dateType, trafficBytes, countRequests) VALUES (?, ?, ?, ?, ?)", userPlanId, day, "day", dailyTotalBytes, dailyCountRequests) if err != nil { var errMessage = strings.ToLower(err.Error()) if !strings.Contains(errMessage, "duplicate") && !strings.Contains(errMessage, "1062") { return err } err = nil } } } // userPlanId _, err = db.Exec("UPDATE "+bandwidthTable+" SET userPlanId=? WHERE serverId=? AND day BETWEEN ? AND ?", userPlanId, serverId, month+"01", month+"31") if err != nil { return err } // userPlanBandwidth { ones, _, err := db.FindOnes("SELECT * FROM "+bandwidthTable+" WHERE serverId=? AND userPlanId=?", serverId, userPlanId) if err != nil { return err } for _, one := range ones { _, err = db.Exec("INSERT INTO edgeUserPlanBandwidthStats_"+types.String(userPlanId%models.UserPlanBandwidthStatTablePartitions)+" (userId, userPlanId, day, timeAt, bytes, regionId, totalBytes, avgBytes, cachedBytes, attackBytes, countRequests, countCachedRequests, countAttackRequests) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", one.GetInt64("userId"), userPlanId, one.GetString("day"), one.GetString("timeAt"), one.GetInt64("bytes"), one.GetInt64("regionId"), one.GetInt64("totalBytes"), one.GetInt64("avgBytes"), one.GetInt64("cachedBytes"), one.GetInt64("attackBytes"), one.GetInt64("countRequests"), one.GetInt64("countCachedRequests"), one.GetInt64("countAttackRequests")) if err != nil { var errMessage = err.Error() if !strings.Contains(errMessage, "duplicate") && !strings.Contains(errMessage, "1062") { return err } } } } } } return nil } userPlans, _, err := db.FindOnes("SELECT id FROM edgeUserPlans WHERE state=1") if err != nil { return err } for _, userPlan := range userPlans { var userPlanId = userPlan.GetInt64("id") servers, _, err := db.FindOnes("SELECT id FROM edgeServers WHERE userPlanId=?", userPlanId) if err != nil { return err } for _, server := range servers { var serverId = server.GetInt64("id") { var lastMonth = timeutil.Format("Ym", time.Now().AddDate(0, -1, 0)) err = upgradeFunc(userPlanId, serverId, lastMonth) if err != nil { return err } } { var month = timeutil.Format("Ym") err = upgradeFunc(userPlanId, serverId, month) if err != nil { return err } } } } } } return nil }