From 0b7ba128256631310ee8af028a7ff27e99c5c57d Mon Sep 17 00:00:00 2001 From: GoEdgeLab Date: Sun, 12 May 2024 17:36:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BA=90=E7=AB=99=E5=A2=9E=E5=8A=A0=E6=89=80?= =?UTF-8?q?=E5=B1=9E=E5=8F=8D=E5=90=91=E4=BB=A3=E7=90=86=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E4=BE=BF=E4=BA=8E=E5=BF=AB=E9=80=9F=E6=9F=A5?= =?UTF-8?q?=E6=89=BE=E6=BA=90=E7=AB=99=E5=AF=B9=E5=BA=94=E7=9A=84=E5=8F=8D?= =?UTF-8?q?=E5=90=91=E4=BB=A3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/db/models/origin_dao.go | 30 +++++++- internal/db/models/origin_model.go | 35 ++++++++++ internal/db/models/reverse_proxy_dao.go | 91 +++++++++++++++++++++---- internal/setup/sql.json | 6 +- 4 files changed, 148 insertions(+), 14 deletions(-) diff --git a/internal/db/models/origin_dao.go b/internal/db/models/origin_dao.go index 986766fe..9c98678c 100644 --- a/internal/db/models/origin_dao.go +++ b/internal/db/models/origin_dao.go @@ -540,10 +540,26 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap * // CheckUserOrigin 检查源站权限 func (this *OriginDAO) CheckUserOrigin(tx *dbs.Tx, userId int64, originId int64) error { - reverseProxyId, err := SharedReverseProxyDAO.FindReverseProxyContainsOriginId(tx, originId) + if originId <= 0 { + return ErrNotFound + } + + // 快速查找 + reverseProxyId, err := this.Query(tx). + Pk(originId). + Result(OriginField_ReverseProxyId). + FindInt64Col(0) if err != nil { return err } + + // 再次查找 + if reverseProxyId <= 0 { + reverseProxyId, err = SharedReverseProxyDAO.FindReverseProxyContainsOriginId(tx, originId) + if err != nil { + return err + } + } if reverseProxyId == 0 { // 这里我们不允许源站没有被使用 return ErrNotFound @@ -562,6 +578,18 @@ func (this *OriginDAO) ExistsOrigin(tx *dbs.Tx, originId int64) (bool, error) { Exist() } +// UpdateOriginReverseProxyId 设置源站所属反向代理ID +func (this *OriginDAO) UpdateOriginReverseProxyId(tx *dbs.Tx, originId int64, reverseProxyId int64) error { + if originId <= 0 || reverseProxyId <= 0 { + return nil + } + + return this.Query(tx). + Pk(originId). + Set(OriginField_ReverseProxyId, reverseProxyId). + UpdateQuickly() +} + // NotifyUpdate 通知更新 func (this *OriginDAO) NotifyUpdate(tx *dbs.Tx, originId int64) error { reverseProxyId, err := SharedReverseProxyDAO.FindReverseProxyContainsOriginId(tx, originId) diff --git a/internal/db/models/origin_model.go b/internal/db/models/origin_model.go index 90ddb1e1..efb46dfc 100644 --- a/internal/db/models/origin_model.go +++ b/internal/db/models/origin_model.go @@ -2,11 +2,45 @@ package models import "github.com/iwind/TeaGo/dbs" +const ( + OriginField_Id dbs.FieldName = "id" // ID + OriginField_AdminId dbs.FieldName = "adminId" // 管理员ID + OriginField_UserId dbs.FieldName = "userId" // 用户ID + OriginField_ReverseProxyId dbs.FieldName = "reverseProxyId" // 所属反向代理ID + OriginField_IsOn dbs.FieldName = "isOn" // 是否启用 + OriginField_Name dbs.FieldName = "name" // 名称 + OriginField_Version dbs.FieldName = "version" // 版本 + OriginField_Addr dbs.FieldName = "addr" // 地址 + OriginField_Oss dbs.FieldName = "oss" // OSS配置 + OriginField_Description dbs.FieldName = "description" // 描述 + OriginField_Code dbs.FieldName = "code" // 代号 + OriginField_Weight dbs.FieldName = "weight" // 权重 + OriginField_ConnTimeout dbs.FieldName = "connTimeout" // 连接超时 + OriginField_ReadTimeout dbs.FieldName = "readTimeout" // 读超时 + OriginField_IdleTimeout dbs.FieldName = "idleTimeout" // 空闲连接超时 + OriginField_MaxFails dbs.FieldName = "maxFails" // 最多失败次数 + OriginField_MaxConns dbs.FieldName = "maxConns" // 最大并发连接数 + OriginField_MaxIdleConns dbs.FieldName = "maxIdleConns" // 最多空闲连接数 + OriginField_HttpRequestURI dbs.FieldName = "httpRequestURI" // 转发后的请求URI + OriginField_HttpRequestHeader dbs.FieldName = "httpRequestHeader" // 请求Header配置 + OriginField_HttpResponseHeader dbs.FieldName = "httpResponseHeader" // 响应Header配置 + OriginField_Host dbs.FieldName = "host" // 自定义主机名 + OriginField_HealthCheck dbs.FieldName = "healthCheck" // 健康检查设置 + OriginField_Cert dbs.FieldName = "cert" // 证书设置 + OriginField_Ftp dbs.FieldName = "ftp" // FTP相关设置 + OriginField_CreatedAt dbs.FieldName = "createdAt" // 创建时间 + OriginField_Domains dbs.FieldName = "domains" // 所属域名 + OriginField_FollowPort dbs.FieldName = "followPort" // 端口跟随 + OriginField_State dbs.FieldName = "state" // 状态 + OriginField_Http2Enabled dbs.FieldName = "http2Enabled" // 是否支持HTTP/2 +) + // Origin 源站 type Origin struct { Id uint32 `field:"id"` // ID AdminId uint32 `field:"adminId"` // 管理员ID UserId uint32 `field:"userId"` // 用户ID + ReverseProxyId uint64 `field:"reverseProxyId"` // 所属反向代理ID IsOn bool `field:"isOn"` // 是否启用 Name string `field:"name"` // 名称 Version uint32 `field:"version"` // 版本 @@ -39,6 +73,7 @@ type OriginOperator struct { Id any // ID AdminId any // 管理员ID UserId any // 用户ID + ReverseProxyId any // 所属反向代理ID IsOn any // 是否启用 Name any // 名称 Version any // 版本 diff --git a/internal/db/models/reverse_proxy_dao.go b/internal/db/models/reverse_proxy_dao.go index bdd22a17..20e0e044 100644 --- a/internal/db/models/reverse_proxy_dao.go +++ b/internal/db/models/reverse_proxy_dao.go @@ -3,6 +3,7 @@ package models import ( "encoding/json" "errors" + "fmt" "github.com/TeaOSLab/EdgeAPI/internal/utils" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" @@ -213,7 +214,24 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI } // CreateReverseProxy 创建反向代理 -func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userId int64, schedulingJSON []byte, primaryOriginsJSON []byte, backupOriginsJSON []byte) (int64, error) { +func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userId int64, schedulingJSON []byte, primaryOriginRefsJSON []byte, backupOriginRefsJSON []byte) (int64, error) { + // decode origins + var primaryOriginRefs []*serverconfigs.OriginRef + if len(primaryOriginRefsJSON) > 0 { + err := json.Unmarshal(primaryOriginRefsJSON, &primaryOriginRefs) + if err != nil { + return 0, fmt.Errorf("decode 'primaryOriginRefs' failed: " + err.Error()) + } + } + + var backupOriginRefs []*serverconfigs.OriginRef + if len(backupOriginRefsJSON) > 0 { + err := json.Unmarshal(backupOriginRefsJSON, &backupOriginRefs) + if err != nil { + return 0, fmt.Errorf("decode 'backupOriginRefs' failed: " + err.Error()) + } + } + var op = NewReverseProxyOperator() op.IsOn = true op.State = ReverseProxyStateEnabled @@ -233,18 +251,35 @@ func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userI if IsNotNull(schedulingJSON) { op.Scheduling = string(schedulingJSON) } - if IsNotNull(primaryOriginsJSON) { - op.PrimaryOrigins = string(primaryOriginsJSON) + if IsNotNull(primaryOriginRefsJSON) { + op.PrimaryOrigins = string(primaryOriginRefsJSON) } - if IsNotNull(backupOriginsJSON) { - op.BackupOrigins = string(backupOriginsJSON) + if IsNotNull(backupOriginRefsJSON) { + op.BackupOrigins = string(backupOriginRefsJSON) } err = this.Save(tx, op) if err != nil { return 0, err } - return types.Int64(op.Id), nil + var reverseProxyId = types.Int64(op.Id) + + // set 'reverseProxyId' of origins + for _, originRef := range primaryOriginRefs { + err = SharedOriginDAO.UpdateOriginReverseProxyId(tx, originRef.OriginId, reverseProxyId) + if err != nil { + return 0, err + } + } + + for _, originRef := range backupOriginRefs { + err = SharedOriginDAO.UpdateOriginReverseProxyId(tx, originRef.OriginId, reverseProxyId) + if err != nil { + return 0, err + } + } + + return reverseProxyId, nil } // CloneReverseProxy 复制反向代理 @@ -376,14 +411,30 @@ func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reversePro } // UpdateReverseProxyPrimaryOrigins 修改主要源站 -func (this *ReverseProxyDAO) UpdateReverseProxyPrimaryOrigins(tx *dbs.Tx, reverseProxyId int64, originRefs []byte) error { +func (this *ReverseProxyDAO) UpdateReverseProxyPrimaryOrigins(tx *dbs.Tx, reverseProxyId int64, originRefsJSON []byte) error { if reverseProxyId <= 0 { return errors.New("invalid reverseProxyId") } + + // set 'reverseProxyId' of origins + if len(originRefsJSON) > 0 { + var originRefs []*serverconfigs.OriginRef + err := json.Unmarshal(originRefsJSON, &originRefs) + if err != nil { + return fmt.Errorf("decode 'originRefs' failed: " + err.Error()) + } + for _, originRef := range originRefs { + err = SharedOriginDAO.UpdateOriginReverseProxyId(tx, originRef.OriginId, reverseProxyId) + if err != nil { + return err + } + } + } + var op = NewReverseProxyOperator() op.Id = reverseProxyId - if len(originRefs) > 0 { - op.PrimaryOrigins = originRefs + if len(originRefsJSON) > 0 { + op.PrimaryOrigins = originRefsJSON } else { op.PrimaryOrigins = "[]" } @@ -395,14 +446,30 @@ func (this *ReverseProxyDAO) UpdateReverseProxyPrimaryOrigins(tx *dbs.Tx, revers } // UpdateReverseProxyBackupOrigins 修改备用源站 -func (this *ReverseProxyDAO) UpdateReverseProxyBackupOrigins(tx *dbs.Tx, reverseProxyId int64, origins []byte) error { +func (this *ReverseProxyDAO) UpdateReverseProxyBackupOrigins(tx *dbs.Tx, reverseProxyId int64, originRefsJSON []byte) error { if reverseProxyId <= 0 { return errors.New("invalid reverseProxyId") } + + // set 'reverseProxyId' of origins + if len(originRefsJSON) > 0 { + var originRefs []*serverconfigs.OriginRef + err := json.Unmarshal(originRefsJSON, &originRefs) + if err != nil { + return fmt.Errorf("decode 'originRefs' failed: " + err.Error()) + } + for _, originRef := range originRefs { + err = SharedOriginDAO.UpdateOriginReverseProxyId(tx, originRef.OriginId, reverseProxyId) + if err != nil { + return err + } + } + } + var op = NewReverseProxyOperator() op.Id = reverseProxyId - if len(origins) > 0 { - op.BackupOrigins = origins + if len(originRefsJSON) > 0 { + op.BackupOrigins = originRefsJSON } else { op.BackupOrigins = "[]" } diff --git a/internal/setup/sql.json b/internal/setup/sql.json index 2bf3194a..7fd80a2c 100644 --- a/internal/setup/sql.json +++ b/internal/setup/sql.json @@ -122371,7 +122371,7 @@ "name": "edgeOrigins", "engine": "InnoDB", "charset": "utf8mb4_general_ci", - "definition": "CREATE TABLE `edgeOrigins` (\n `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `adminId` int(11) unsigned DEFAULT '0' COMMENT '管理员ID',\n `userId` int(11) unsigned DEFAULT '0' COMMENT '用户ID',\n `isOn` tinyint(1) unsigned DEFAULT '1' COMMENT '是否启用',\n `name` varchar(255) DEFAULT NULL COMMENT '名称',\n `version` int(11) unsigned DEFAULT '0' COMMENT '版本',\n `addr` json DEFAULT NULL COMMENT '地址',\n `oss` json DEFAULT NULL COMMENT 'OSS配置',\n `description` varchar(512) DEFAULT NULL COMMENT '描述',\n `code` varchar(255) DEFAULT NULL COMMENT '代号',\n `weight` int(11) unsigned DEFAULT '0' COMMENT '权重',\n `connTimeout` json DEFAULT NULL COMMENT '连接超时',\n `readTimeout` json DEFAULT NULL COMMENT '读超时',\n `idleTimeout` json DEFAULT NULL COMMENT '空闲连接超时',\n `maxFails` int(11) unsigned DEFAULT '0' COMMENT '最多失败次数',\n `maxConns` int(11) unsigned DEFAULT '0' COMMENT '最大并发连接数',\n `maxIdleConns` int(11) unsigned DEFAULT '0' COMMENT '最多空闲连接数',\n `httpRequestURI` varchar(1024) DEFAULT NULL COMMENT '转发后的请求URI',\n `httpRequestHeader` json DEFAULT NULL COMMENT '请求Header配置',\n `httpResponseHeader` json DEFAULT NULL COMMENT '响应Header配置',\n `host` varchar(255) DEFAULT NULL COMMENT '自定义主机名',\n `healthCheck` json DEFAULT NULL COMMENT '健康检查设置',\n `cert` json DEFAULT NULL COMMENT '证书设置',\n `ftp` json DEFAULT NULL COMMENT 'FTP相关设置',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `domains` json DEFAULT NULL COMMENT '所属域名',\n `followPort` tinyint(1) unsigned DEFAULT '0' COMMENT '端口跟随',\n `state` tinyint(1) unsigned DEFAULT '1' COMMENT '状态',\n `http2Enabled` tinyint(1) unsigned DEFAULT '0' COMMENT '是否支持HTTP/2',\n PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='源站'", + "definition": "CREATE TABLE `edgeOrigins` (\n `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `adminId` int(11) unsigned DEFAULT '0' COMMENT '管理员ID',\n `userId` int(11) unsigned DEFAULT '0' COMMENT '用户ID',\n `reverseProxyId` bigint(11) unsigned DEFAULT '0' COMMENT '所属反向代理ID',\n `isOn` tinyint(1) unsigned DEFAULT '1' COMMENT '是否启用',\n `name` varchar(255) DEFAULT NULL COMMENT '名称',\n `version` int(11) unsigned DEFAULT '0' COMMENT '版本',\n `addr` json DEFAULT NULL COMMENT '地址',\n `oss` json DEFAULT NULL COMMENT 'OSS配置',\n `description` varchar(512) DEFAULT NULL COMMENT '描述',\n `code` varchar(255) DEFAULT NULL COMMENT '代号',\n `weight` int(11) unsigned DEFAULT '0' COMMENT '权重',\n `connTimeout` json DEFAULT NULL COMMENT '连接超时',\n `readTimeout` json DEFAULT NULL COMMENT '读超时',\n `idleTimeout` json DEFAULT NULL COMMENT '空闲连接超时',\n `maxFails` int(11) unsigned DEFAULT '0' COMMENT '最多失败次数',\n `maxConns` int(11) unsigned DEFAULT '0' COMMENT '最大并发连接数',\n `maxIdleConns` int(11) unsigned DEFAULT '0' COMMENT '最多空闲连接数',\n `httpRequestURI` varchar(1024) DEFAULT NULL COMMENT '转发后的请求URI',\n `httpRequestHeader` json DEFAULT NULL COMMENT '请求Header配置',\n `httpResponseHeader` json DEFAULT NULL COMMENT '响应Header配置',\n `host` varchar(255) DEFAULT NULL COMMENT '自定义主机名',\n `healthCheck` json DEFAULT NULL COMMENT '健康检查设置',\n `cert` json DEFAULT NULL COMMENT '证书设置',\n `ftp` json DEFAULT NULL COMMENT 'FTP相关设置',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `domains` json DEFAULT NULL COMMENT '所属域名',\n `followPort` tinyint(1) unsigned DEFAULT '0' COMMENT '端口跟随',\n `state` tinyint(1) unsigned DEFAULT '1' COMMENT '状态',\n `http2Enabled` tinyint(1) unsigned DEFAULT '0' COMMENT '是否支持HTTP/2',\n PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='源站'", "fields": [ { "name": "id", @@ -122385,6 +122385,10 @@ "name": "userId", "definition": "int(11) unsigned DEFAULT '0' COMMENT '用户ID'" }, + { + "name": "reverseProxyId", + "definition": "bigint(11) unsigned DEFAULT '0' COMMENT '所属反向代理ID'" + }, { "name": "isOn", "definition": "tinyint(1) unsigned DEFAULT '1' COMMENT '是否启用'"