mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-08 15:51:11 +08:00
迁出网站监控表、新增西部数码和火山引擎dns
This commit is contained in:
@@ -19,6 +19,8 @@ import (
|
||||
"github.com/go-acme/lego/v4/providers/dns/cloudflare"
|
||||
"github.com/go-acme/lego/v4/providers/dns/huaweicloud"
|
||||
"github.com/go-acme/lego/v4/providers/dns/tencentcloud"
|
||||
"github.com/go-acme/lego/v4/providers/dns/volcengine"
|
||||
"github.com/go-acme/lego/v4/providers/dns/westcn"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -64,12 +66,23 @@ func GetDNSProvider(providerName string, creds map[string]string) (challenge.Pro
|
||||
config.AccessKeyID = creds["access_key"]
|
||||
config.SecretAccessKey = creds["secret_key"]
|
||||
return baiducloud.NewDNSProviderConfig(config)
|
||||
case "westcn":
|
||||
config := westcn.NewDefaultConfig()
|
||||
config.Username = creds["username"]
|
||||
config.Password = creds["password"]
|
||||
return westcn.NewDNSProviderConfig(config)
|
||||
case "volcengine":
|
||||
config := volcengine.NewDefaultConfig()
|
||||
config.AccessKey = creds["access_key"]
|
||||
config.SecretKey = creds["secret_key"]
|
||||
return volcengine.NewDNSProviderConfig(config)
|
||||
|
||||
// case "godaddy":
|
||||
// config := godaddy.NewDefaultConfig()
|
||||
// config.APIKey = creds["api_key"]
|
||||
// config.APISecret = creds["api_secret"]
|
||||
// return godaddy.NewDNSProviderConfig(config)
|
||||
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("不支持的 DNS Provider: %s", providerName)
|
||||
}
|
||||
@@ -81,7 +94,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
|
||||
email, ok := cfg["email"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("参数错误:email")
|
||||
@@ -119,7 +132,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
return nil, fmt.Errorf("参数错误:name_server")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var skipCheck bool
|
||||
if cfg["skip_check"] == nil {
|
||||
skipCheck = true
|
||||
@@ -149,12 +162,12 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
return nil, fmt.Errorf("参数错误:skip_check")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
domainArr := strings.Split(domains, ",")
|
||||
for i := range domainArr {
|
||||
domainArr[i] = strings.TrimSpace(domainArr[i])
|
||||
}
|
||||
|
||||
|
||||
// 获取上次申请的证书
|
||||
runId, ok := cfg["_runId"].(string)
|
||||
if !ok {
|
||||
@@ -207,7 +220,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
if !ok || cfgEnd <= 0 {
|
||||
cfgEnd = 30
|
||||
}
|
||||
|
||||
|
||||
if int(maxDays) > cfgEnd {
|
||||
// 证书未过期,直接返回
|
||||
logger.Debug(fmt.Sprintf("上次证书申请成功,域名:%s,剩余天数:%d 大于%d天,已跳过申请复用此证书", certObj["domains"], int(maxDays), cfgEnd))
|
||||
@@ -221,7 +234,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
}
|
||||
}
|
||||
logger.Debug("正在申请证书,域名: " + domains)
|
||||
|
||||
|
||||
user, err := LoadUserFromDB(db, email)
|
||||
if err != nil {
|
||||
logger.Debug("acme账号不存在,注册新账号")
|
||||
@@ -230,10 +243,10 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
Email: email,
|
||||
key: privateKey,
|
||||
}
|
||||
|
||||
|
||||
config := lego.NewConfig(user)
|
||||
config.Certificate.KeyType = certcrypto.EC384
|
||||
|
||||
|
||||
client, err := lego.NewClient(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -244,14 +257,14 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
return nil, err
|
||||
}
|
||||
user.Registration = reg
|
||||
|
||||
|
||||
err = SaveUserToDB(db, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logger.Debug("账号注册并保存成功")
|
||||
}
|
||||
|
||||
|
||||
// 初始化 ACME 客户端
|
||||
client, err := lego.NewClient(lego.NewConfig(user))
|
||||
if err != nil {
|
||||
@@ -272,13 +285,13 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// DNS 验证
|
||||
provider, err := GetDNSProvider(providerStr, providerConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建 DNS provider 失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
if skipCheck {
|
||||
// 跳过预检查
|
||||
err = client.Challenge.SetDNS01Provider(provider,
|
||||
@@ -295,7 +308,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// fmt.Println(strings.Split(domains, ","))
|
||||
request := certificate.ObtainRequest{
|
||||
Domains: domainArr,
|
||||
@@ -305,18 +318,18 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
certStr := string(certObj.Certificate)
|
||||
keyStr := string(certObj.PrivateKey)
|
||||
issuerCertStr := string(certObj.IssuerCertificate)
|
||||
|
||||
|
||||
// 保存证书和私钥
|
||||
data := map[string]any{
|
||||
"cert": certStr,
|
||||
"key": keyStr,
|
||||
"issuerCert": issuerCertStr,
|
||||
}
|
||||
|
||||
|
||||
_, err = cert.SaveCert("workflow", keyStr, certStr, issuerCertStr, runId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -53,7 +53,7 @@ func DeployToTX(cfg map[string]any) error {
|
||||
if !ok {
|
||||
return fmt.Errorf("证书错误:cert")
|
||||
}
|
||||
|
||||
|
||||
var providerID string
|
||||
switch v := cfg["provider_id"].(type) {
|
||||
case float64:
|
||||
@@ -83,16 +83,16 @@ func DeployToTX(cfg map[string]any) error {
|
||||
region = r
|
||||
}
|
||||
client := ClientTencentcloud(providerConfig["secret_id"], providerConfig["secret_key"], region)
|
||||
|
||||
|
||||
// 上传证书
|
||||
certificateId, err := UploadToTX(client, strings.TrimSpace(keyPem), strings.TrimSpace(certPem))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// fmt.Println(certificateId)
|
||||
|
||||
|
||||
request := ssl.NewDeployCertificateInstanceRequest()
|
||||
|
||||
|
||||
request.CertificateId = common.StringPtr(certificateId)
|
||||
if cfg["resource_type"] == "cdn" {
|
||||
domain, ok := cfg["domain"].(string)
|
||||
@@ -103,7 +103,6 @@ func DeployToTX(cfg map[string]any) error {
|
||||
request.ResourceType = common.StringPtr("cdn")
|
||||
}
|
||||
if cfg["resource_type"] == "cos" {
|
||||
// fmt.Println(fmt.Sprintf("%s|%s|%s", cfg["region"].(string), cfg["bucket"].(string), cfg["domain"].(string)))
|
||||
domain, ok := cfg["domain"].(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("参数错误:domain")
|
||||
@@ -117,10 +116,9 @@ func DeployToTX(cfg map[string]any) error {
|
||||
return fmt.Errorf("参数错误:bucket")
|
||||
}
|
||||
request.InstanceIdList = common.StringPtrs([]string{fmt.Sprintf("%s|%s|%s", region, bucket, domain)})
|
||||
// request.InstanceIdList = common.StringPtrs([]string{"ap-guangzhou#allinssl-1253163109#allinssl.zachyang.cn"})
|
||||
request.ResourceType = common.StringPtr("cos")
|
||||
}
|
||||
|
||||
|
||||
// 返回的resp是一个DeployCertificateInstanceResponse的实例,与请求对象对应
|
||||
response, err := client.DeployCertificateInstance(request)
|
||||
if _, ok := err.(*errors.TencentCloudSDKError); ok {
|
||||
|
||||
@@ -67,7 +67,7 @@ func GetCertCount() (map[string]int, error) {
|
||||
}
|
||||
|
||||
func GetSiteMonitorCount() (map[string]any, error) {
|
||||
s, err := public.NewSqlite("data/data.db", "")
|
||||
s, err := public.NewSqlite("data/site_monitor.db", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -126,7 +126,7 @@ func GetWorkflowHistory() ([]map[string]any, error) {
|
||||
} else {
|
||||
name = "未知"
|
||||
}
|
||||
|
||||
|
||||
result = append(result, map[string]any{
|
||||
"name": name,
|
||||
"state": state,
|
||||
|
||||
@@ -25,7 +25,7 @@ type SSLInfo struct {
|
||||
}
|
||||
|
||||
func GetSqlite() (*public.Sqlite, error) {
|
||||
s, err := public.NewSqlite("data/data.db", "")
|
||||
s, err := public.NewSqlite("data/site_monitor.db", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package migrations
|
||||
|
||||
import (
|
||||
"ALLinSSL/backend/public"
|
||||
"ALLinSSL/backend/public/sqlite_migrate"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
_ "modernc.org/sqlite"
|
||||
@@ -122,28 +123,7 @@ func init() {
|
||||
active integer not null,
|
||||
type TEXT
|
||||
);
|
||||
|
||||
create table IF NOT EXISTS site_monitor
|
||||
(
|
||||
id integer not null
|
||||
constraint site_monitor_pk
|
||||
primary key autoincrement,
|
||||
name TEXT not null,
|
||||
site_domain TEXT not null,
|
||||
cycle integer not null,
|
||||
report_type TEXT not null,
|
||||
cert_domain TEXT,
|
||||
ca TEXT,
|
||||
active integer,
|
||||
end_time TEXT,
|
||||
end_day TEXT,
|
||||
last_time TEXT,
|
||||
except_end_time TEXT,
|
||||
create_time TEXT,
|
||||
state TEXT,
|
||||
update_time TEXT,
|
||||
repeat_send_gap INTEGER
|
||||
);
|
||||
|
||||
|
||||
create table IF NOT EXISTS users
|
||||
(
|
||||
@@ -238,8 +218,54 @@ INSERT INTO settings (key, value, create_time, update_time, active, type) VALUES
|
||||
|
||||
InsertIfNotExists(db, "access_type", map[string]any{"name": "btwaf", "type": "host"}, []string{"name", "type"}, []any{"btwaf", "host"})
|
||||
|
||||
// 雷池
|
||||
InsertIfNotExists(db, "access_type", map[string]any{"name": "safeline", "type": "host"}, []string{"name", "type"}, []any{"safeline", "host"})
|
||||
// 西部数码
|
||||
InsertIfNotExists(db, "access_type", map[string]any{"name": "westcn", "type": "dns"}, []string{"name", "type"}, []any{"westcn", "dns"})
|
||||
// 火山引擎
|
||||
InsertIfNotExists(db, "access_type", map[string]any{"name": "volcengine", "type": "dns"}, []string{"name", "type"}, []any{"volcengine", "dns"})
|
||||
|
||||
err = sqlite_migrate.EnsureDatabaseWithTables(
|
||||
"data/site_monitor.db",
|
||||
"data/data.db",
|
||||
[]string{"site_monitor"}, // 你要迁移的表
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("错误:", err)
|
||||
}
|
||||
|
||||
db1, err := sql.Open("sqlite", "data/site_monitor.db")
|
||||
if err != nil {
|
||||
// fmt.Println("创建数据库失败:", err)
|
||||
return
|
||||
}
|
||||
defer db1.Close()
|
||||
// 创建表
|
||||
_, err = db1.Exec(`
|
||||
PRAGMA journal_mode=WAL;
|
||||
|
||||
create table IF NOT EXISTS site_monitor
|
||||
(
|
||||
id integer not null
|
||||
constraint site_monitor_pk
|
||||
primary key autoincrement,
|
||||
name TEXT not null,
|
||||
site_domain TEXT not null,
|
||||
cycle integer not null,
|
||||
report_type TEXT not null,
|
||||
cert_domain TEXT,
|
||||
ca TEXT,
|
||||
active integer,
|
||||
end_time TEXT,
|
||||
end_day TEXT,
|
||||
last_time TEXT,
|
||||
except_end_time TEXT,
|
||||
create_time TEXT,
|
||||
state TEXT,
|
||||
update_time TEXT,
|
||||
repeat_send_gap INTEGER
|
||||
);
|
||||
`)
|
||||
}
|
||||
|
||||
func insertDefaultData(db *sql.DB, table, insertSQL string) {
|
||||
|
||||
23
backend/public/sqlite_migrate/m_test.go
Normal file
23
backend/public/sqlite_migrate/m_test.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package sqlite_migrate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
err := os.Chdir("D:/code/ALLinSSL")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "切换目录失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
err = EnsureDatabaseWithTables(
|
||||
"data/111.db",
|
||||
"data/data.db",
|
||||
[]string{"1111"}, // 你要迁移的表
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("错误:", err)
|
||||
}
|
||||
}
|
||||
107
backend/public/sqlite_migrate/migrate_table_to_db.go
Normal file
107
backend/public/sqlite_migrate/migrate_table_to_db.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package sqlite_migrate
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
_ "modernc.org/sqlite" // 使用 pure Go 实现的 SQLite 驱动
|
||||
)
|
||||
|
||||
func EnsureDatabaseWithTables(targetDBPath string, baseDBPath string, tables []string) error {
|
||||
// 1. 检查数据库是否存在
|
||||
if _, err := os.Stat(targetDBPath); err == nil {
|
||||
fmt.Printf("数据库 %s 已存在,跳过迁移。\n", targetDBPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("数据库 %s 不存在,开始从基础数据库迁移表...\n", targetDBPath)
|
||||
|
||||
// 2. 打开源数据库(只读)和目标数据库(新建)
|
||||
baseDB, err := sql.Open("sqlite", baseDBPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("打开基础数据库失败: %v", err)
|
||||
}
|
||||
defer baseDB.Close()
|
||||
|
||||
targetDB, err := sql.Open("sqlite", targetDBPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建目标数据库失败: %v", err)
|
||||
}
|
||||
defer targetDB.Close()
|
||||
|
||||
for _, table := range tables {
|
||||
// 2.1 获取建表语句
|
||||
var createSQL string
|
||||
query := "SELECT sql FROM sqlite_master WHERE type='table' AND name=?"
|
||||
err = baseDB.QueryRow(query, table).Scan(&createSQL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取表 %s 的结构失败: %v", table, err)
|
||||
}
|
||||
|
||||
// 2.2 在目标库中创建表
|
||||
_, err = targetDB.Exec(createSQL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建表 %s 失败: %v", table, err)
|
||||
}
|
||||
|
||||
// 2.3 从基础库读取数据并插入目标库
|
||||
rows, err := baseDB.Query(fmt.Sprintf("SELECT * FROM %s", table))
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取表 %s 数据失败: %v", table, err)
|
||||
}
|
||||
|
||||
cols, _ := rows.Columns()
|
||||
values := make([]interface{}, len(cols))
|
||||
valuePtrs := make([]interface{}, len(cols))
|
||||
|
||||
tx, _ := targetDB.Begin()
|
||||
stmt, _ := tx.Prepare(buildInsertSQL(table, len(cols)))
|
||||
|
||||
for rows.Next() {
|
||||
for i := range values {
|
||||
valuePtrs[i] = &values[i]
|
||||
}
|
||||
rows.Scan(valuePtrs...)
|
||||
stmt.Exec(values...)
|
||||
}
|
||||
|
||||
stmt.Close()
|
||||
tx.Commit()
|
||||
rows.Close()
|
||||
}
|
||||
|
||||
fmt.Println("迁移完成。")
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildInsertSQL(table string, numCols int) string {
|
||||
placeholders := make([]string, numCols)
|
||||
for i := range placeholders {
|
||||
placeholders[i] = "?"
|
||||
}
|
||||
return fmt.Sprintf("INSERT INTO %s VALUES (%s)", table, joinStrings(placeholders, ","))
|
||||
}
|
||||
|
||||
func joinStrings(strs []string, sep string) string {
|
||||
result := ""
|
||||
for i, s := range strs {
|
||||
if i > 0 {
|
||||
result += sep
|
||||
}
|
||||
result += s
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 示例用法
|
||||
func main() {
|
||||
err := EnsureDatabaseWithTables(
|
||||
"./target.db",
|
||||
"./base.db",
|
||||
[]string{"users", "products"}, // 你要迁移的表
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("错误:", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user