增加ip2region库管理

This commit is contained in:
GoEdgeLab
2020-11-04 15:50:53 +08:00
parent 7eb41f5580
commit 7f4bd06bbb
13 changed files with 408 additions and 0 deletions

View File

@@ -172,6 +172,18 @@ func (this *RPCClient) MessageRPC() pb.MessageServiceClient {
return pb.NewMessageServiceClient(this.pickConn())
}
func (this *RPCClient) IPLibraryRPC() pb.IPLibraryServiceClient {
return pb.NewIPLibraryServiceClient(this.pickConn())
}
func (this *RPCClient) FileRPC() pb.FileServiceClient {
return pb.NewFileServiceClient(this.pickConn())
}
func (this *RPCClient) FileChunkRPC() pb.FileChunkServiceClient {
return pb.NewFileChunkServiceClient(this.pickConn())
}
// 构造Admin上下文
func (this *RPCClient) Context(adminId int64) context.Context {
ctx := context.Background()

View File

@@ -64,6 +64,11 @@ func (this *ComponentHelper) createLeftMenus(secondMenuItem string) (items []map
"url": "/servers/components/ssl",
"isActive": secondMenuItem == "ssl",
})
items = append(items, maps.Map{
"name": "IP库",
"url": "/servers/components/ip-library",
"isActive": secondMenuItem == "ip-library",
})
/**items = append(items, maps.Map{
"name": "Gzip规则",
"url": "/servers/components/gzip",

View File

@@ -0,0 +1,22 @@
package iplibrary
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
type DeleteAction struct {
actionutils.ParentAction
}
func (this *DeleteAction) RunPost(params struct {
LibraryId int64
}) {
_, err := this.RPC().IPLibraryRPC().DeleteIPLibrary(this.AdminContext(), &pb.DeleteIPLibraryRequest{IpLibraryId: params.LibraryId})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,46 @@
package iplibrary
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
type DownloadAction struct {
actionutils.ParentAction
}
func (this *DownloadAction) Init() {
this.Nav("", "", "")
}
func (this *DownloadAction) RunGet(params struct {
LibraryId int64
}) {
libraryResp, err := this.RPC().IPLibraryRPC().FindEnabledIPLibrary(this.AdminContext(), &pb.FindEnabledIPLibraryRequest{IpLibraryId: params.LibraryId})
if err != nil {
this.ErrorPage(err)
return
}
if libraryResp.IpLibrary == nil || libraryResp.IpLibrary.File == nil {
this.NotFound("ipLibrary", params.LibraryId)
return
}
file := libraryResp.IpLibrary.File
chunkIdsResp, err := this.RPC().FileChunkRPC().FindAllFileChunkIds(this.AdminContext(), &pb.FindAllFileChunkIdsRequest{FileId: file.Id})
if err != nil {
this.ErrorPage(err)
}
this.AddHeader("Content-Disposition", "attachment; filename=\""+file.Filename+"\";")
for _, chunkId := range chunkIdsResp.FileChunkIds {
chunkResp, err := this.RPC().FileChunkRPC().DownloadFileChunk(this.AdminContext(), &pb.DownloadFileChunkRequest{FileChunkId: chunkId})
if err != nil {
this.ErrorPage(err)
return
}
if chunkResp.FileChunk != nil {
this.Write(chunkResp.FileChunk.Data)
}
}
}

View File

@@ -0,0 +1,22 @@
package iplibrary
import (
"github.com/iwind/TeaGo/actions"
"net/http"
)
type Helper struct {
}
func NewHelper() *Helper {
return &Helper{}
}
func (this *Helper) BeforeAction(action *actions.ActionObject) {
if action.Request.Method != http.MethodGet {
return
}
action.Data["mainTab"] = "component"
action.Data["secondMenuItem"] = "ip-library"
}

View File

@@ -0,0 +1,56 @@
package iplibrary
import (
"fmt"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.FirstMenu("index")
}
func (this *IndexAction) RunGet(params struct {
Type string
}) {
if len(params.Type) == 0 {
params.Type = serverconfigs.IPLibraryTypes[0].GetString("code")
}
this.Data["types"] = serverconfigs.IPLibraryTypes
this.Data["selectedType"] = params.Type
// 列表
listResp, err := this.RPC().IPLibraryRPC().FindAllEnabledIPLibrariesWithType(this.AdminContext(), &pb.FindAllEnabledIPLibrariesWithTypeRequest{Type: params.Type})
if err != nil {
this.ErrorPage(err)
return
}
libraryMaps := []maps.Map{}
for _, library := range listResp.IpLibraries {
var fileMap maps.Map = nil
if library.File != nil {
fileMap = maps.Map{
"id": library.File.Id,
"filename": library.File.Filename,
"sizeMB": fmt.Sprintf("%.2f", float64(library.File.Size)/1024/1024),
}
}
libraryMaps = append(libraryMaps, maps.Map{
"id": library.Id,
"file": fileMap,
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", library.CreatedAt),
})
}
this.Data["libraries"] = libraryMaps
this.Show()
}

View File

@@ -0,0 +1,22 @@
package iplibrary
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/componentutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth()).
Helper(NewHelper()).
Helper(componentutils.NewComponentHelper()).
Prefix("/servers/components/ip-library").
Get("", new(IndexAction)).
GetPost("/uploadPopup", new(UploadPopupAction)).
Post("/delete", new(DeleteAction)).
Get("/download", new(DownloadAction)).
EndAll()
})
}

View File

@@ -0,0 +1,106 @@
package iplibrary
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/actions"
"io"
)
type UploadPopupAction struct {
actionutils.ParentAction
}
func (this *UploadPopupAction) Init() {
this.Nav("", "", "")
}
func (this *UploadPopupAction) RunGet(params struct{}) {
this.Data["types"] = serverconfigs.IPLibraryTypes
this.Show()
}
func (this *UploadPopupAction) RunPost(params struct {
Type string
File *actions.File
Must *actions.Must
}) {
libraryType := serverconfigs.FindIPLibraryWithType(params.Type)
if libraryType == nil {
this.Fail("错误的IP类型")
}
if params.File == nil {
this.Fail("请选择要上传的文件")
}
if params.File.Size == 0 {
this.Fail("文件内容不能为空")
}
if params.File.Ext != libraryType.GetString("ext") {
this.Fail("IP库文件扩展名错误应该为" + libraryType.GetString("ext"))
}
reader, err := params.File.OriginFile.Open()
if err != nil {
this.ErrorPage(err)
return
}
defer func() {
_ = reader.Close()
}()
// 创建文件
fileResp, err := this.RPC().FileRPC().CreateFile(this.AdminContext(), &pb.CreateFileRequest{
Filename: params.File.Filename,
Size: params.File.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
fileId := fileResp.FileId
// 上传内容
buf := make([]byte, 512*1024)
for {
n, err := reader.Read(buf)
if n > 0 {
_, err = this.RPC().FileChunkRPC().CreateFileChunk(this.AdminContext(), &pb.CreateFileChunkRequest{
FileId: fileId,
Data: buf[:n],
})
if err != nil {
this.Fail("上传失败:" + err.Error())
}
}
if err != nil {
if err == io.EOF {
break
}
this.Fail("上传失败:" + err.Error())
}
}
// 置为已完成
_, err = this.RPC().FileRPC().UpdateFileFinished(this.AdminContext(), &pb.UpdateFileFinishedRequest{FileId: fileId})
if err != nil {
this.ErrorPage(err)
}
// 保存
_, err = this.RPC().IPLibraryRPC().CreateIPLibrary(this.AdminContext(), &pb.CreateIPLibraryRequest{
Type: params.Type,
FileId: fileId,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -21,6 +21,7 @@ import (
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/groups"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/ip-library"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/log"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/ssl"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/waf"

View File

@@ -0,0 +1,39 @@
{$layout}
{$template "/left_menu"}
<div class="right-box">
<first-menu>
<menu-item v-for="type in types" :href="'/servers/components/ip-library?type=' + type.code" :active="type.code == selectedType">{{type.name}}</menu-item>
<span class="item">|</span>
<a href="" class="item" @click.prevent="upload()">[上传]</a>
</first-menu>
<p class="comment" v-if="libraries.length == 0">暂时还没有IP库。</p>
<div v-if="libraries.length > 0">
<div class="margin"></div>
<table class="ui table selectable">
<thead>
<tr>
<th>文件名</th>
<th>文件尺寸</th>
<th>上传时间</th>
<th class="two op">操作</th>
</tr>
</thead>
<tr v-for="library in libraries">
<td>
<span v-if="library.file != null">{{library.file.filename}}</span>
<span v-else>-</span>
</td>
<td>
<span v-if="library.file != null">{{library.file.sizeMB}}MB</span>
<span v-else>-</span>
</td>
<td>{{library.createdTime}}</td>
<td>
<a :href="'/servers/components/ip-library/download?libraryId=' + library.id" target="_blank">下载</a> &nbsp; <a href="" @click.prevent="deleteLibrary(library.id)">删除</a>
</td>
</tr>
</table>
</div>
</div>

View File

@@ -0,0 +1,24 @@
Tea.context(function () {
this.upload = function () {
teaweb.popup("/servers/components/ip-library/uploadPopup", {
callback: function () {
teaweb.success("上传成功", function () {
teaweb.reload()
})
}
})
}
this.deleteLibrary = function (libraryId) {
let that = this
teaweb.confirm("确定要删除此IP库吗", function () {
that.$post(".delete")
.params({
"libraryId": libraryId
})
.success(function () {
teaweb.reload()
})
})
}
})

View File

@@ -0,0 +1,25 @@
{$layout "layout_popup"}
<h3>上传IP库</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success" data-tea-timeout="120" data-tea-before="before" data-tea-done="done">
<table class="ui table definition selectable">
<tr>
<td>IP库类型 *</td>
<td>
<select name="type" class="ui dropdown auto-width" @change="changeType()" v-model="selectedTypeCode">
<option v-for="type in types" :value="type.code">{{type.name}}</option>
</select>
<p class="comment">{{selectedTypeDescription}}</p>
</td>
</tr>
<tr>
<td class="title">选择IP库文件 *</td>
<td>
<input type="file" name="file" :accept="selectedTypeExt"/>
</td>
</tr>
</table>
<submit-btn v-if="!isRequesting"></submit-btn>
<button class="ui button disabled" type="button" v-if="isRequesting">上传中...</button>
</form>

View File

@@ -0,0 +1,28 @@
Tea.context(function () {
this.isRequesting = false
this.selectedTypeCode = this.types[0].code
this.selectedTypeDescription = this.types[0].description
this.selectedTypeExt = this.types[0].ext
this.success = NotifyPopup
this.before = function () {
this.isRequesting = true
}
this.done = function () {
this.isRequesting = false
}
this.changeType = function () {
let that = this
let selectedType = this.types.$find(function (k, v) {
return v.code == that.selectedTypeCode
})
if (selectedType == null) {
return
}
this.selectedTypeDescription = selectedType.description
this.selectedTypeExt = selectedType.ext
}
})