1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-31 14:08:06 +08:00

feat: 反向代理增加编辑功能

This commit is contained in:
zhengkunwang223 2023-04-24 11:29:48 +08:00 committed by zhengkunwang223
parent d900b52a50
commit 2dd88364f8
7 changed files with 159 additions and 35 deletions

View File

@ -19,7 +19,6 @@ import (
"path"
"reflect"
"regexp"
"strconv"
"strings"
"time"
@ -1164,7 +1163,7 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error)
switch req.Operate {
case "create":
_ = fileOp.DeleteFile(includePath)
case "update":
case "edit":
_ = fileOp.WriteFile(includePath, bytes.NewReader(oldContent), 0755)
}
}
@ -1175,7 +1174,7 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error)
switch req.Operate {
case "create":
config = parser.NewStringParser(string(nginx_conf.Proxy)).Parse()
case "update":
case "edit":
par, err = parser.NewParser(includePath)
if err != nil {
return
@ -1193,6 +1192,11 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error)
backPath := path.Join(includeDir, backName)
_ = fileOp.Rename(includePath, backPath)
return updateNginxConfig(constant.NginxScopeServer, nil, &website)
case "enable":
backName := fmt.Sprintf("%s.bak", req.Name)
backPath := path.Join(includeDir, backName)
_ = fileOp.Rename(backPath, includePath)
return updateNginxConfig(constant.NginxScopeServer, nil, &website)
}
config.FilePath = includePath
directives := config.Directives
@ -1205,15 +1209,14 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error)
location.UpdateDirective("proxy_set_header", []string{"Host", req.ProxyHost})
location.ChangePath(req.Modifier, req.Match)
if req.Cache {
location.AddCache(strconv.Itoa(req.CacheTime) + req.CacheUnit)
location.AddCache(req.CacheTime, req.CacheUnit)
} else {
location.RemoveCache()
}
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return buserr.WithErr(constant.ErrUpdateBuWebsite, err)
}
nginxInclude := path.Join("www", "sites", website.Alias, "proxy", "*.conf")
nginxInclude := fmt.Sprintf("/www/sites/%s/proxy/*.conf", website.Alias)
if err = updateNginxConfig(constant.NginxScopeServer, []dto.NginxParam{{Name: "include", Params: []string{nginxInclude}}}, &website); err != nil {
return
}
@ -1248,7 +1251,9 @@ func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, e
config *components.Config
)
for _, configFile := range fileList.Items {
proxyConfig := request.WebsiteProxyConfig{}
proxyConfig := request.WebsiteProxyConfig{
ID: website.ID,
}
parts := strings.Split(configFile.Name, ".")
proxyConfig.Name = parts[0]
if parts[1] == "conf" {
@ -1271,8 +1276,13 @@ func (w WebsiteService) GetProxies(id uint) (res []request.WebsiteProxyConfig, e
}
proxyConfig.ProxyPass = location.ProxyPass
proxyConfig.Cache = location.Cache
//proxyConfig.CacheTime = location.CacheTime
if location.CacheTime > 0 {
proxyConfig.CacheTime = location.CacheTime
proxyConfig.CacheUnit = location.CacheUint
}
proxyConfig.Match = location.Match
proxyConfig.Modifier = location.Modifier
proxyConfig.ProxyHost = location.Host
res = append(res, proxyConfig)
}
return

View File

@ -1,13 +1,18 @@
package components
type Location struct {
Modifier string
Match string
Cache bool
ProxyPass string
Host string
CacheTime string
import (
"regexp"
"strconv"
)
type Location struct {
Modifier string
Match string
Cache bool
ProxyPass string
Host string
CacheTime int
CacheUint string
Comment string
Directives []IDirective
Line int
@ -40,7 +45,18 @@ func NewLocation(directive IDirective) *Location {
dirs := dir.GetBlock().GetDirectives()
for _, di := range dirs {
if di.GetName() == "expires" {
location.CacheTime = di.GetParameters()[0]
re := regexp.MustCompile(`^(\d+)(\w+)$`)
matches := re.FindStringSubmatch(di.GetParameters()[0])
if matches == nil {
continue
}
cacheTime, err := strconv.Atoi(matches[1])
if err != nil {
continue
}
unit := matches[2]
location.CacheUint = unit
location.CacheTime = cacheTime
}
}
}
@ -158,7 +174,7 @@ func (l *Location) ChangePath(Modifier string, Match string) {
l.Match = Match
}
func (l *Location) AddCache(cacheTime string) {
func (l *Location) AddCache(cacheTime int, cacheUint string) {
l.RemoveDirective("add_header", []string{"Cache-Control", "no-cache"})
directives := l.GetDirectives()
newDir := &Directive{
@ -169,7 +185,7 @@ func (l *Location) AddCache(cacheTime string) {
block := &Block{}
block.Directives = append(block.Directives, &Directive{
Name: "expires",
Parameters: []string{cacheTime},
Parameters: []string{strconv.Itoa(cacheTime) + cacheUint},
})
newDir.Block = block
directives = append(directives, newDir)
@ -180,6 +196,7 @@ func (l *Location) AddCache(cacheTime string) {
l.UpdateDirective("proxy_cache_valid", []string{"200", "304", "301", "302", "10m"})
l.Cache = true
l.CacheTime = cacheTime
l.CacheUint = cacheUint
}
func (l *Location) RemoveCache() {
@ -191,6 +208,7 @@ func (l *Location) RemoveCache() {
l.UpdateDirective("add_header", []string{"Cache-Control", "no-cache"})
l.CacheTime = ""
l.CacheTime = 0
l.CacheUint = ""
l.Cache = false
}

View File

@ -423,9 +423,6 @@ const message = {
remoteConn: 'External connection address',
remoteConnHelper2: 'Use this address for non-container or external connections',
localIP: 'Local IP',
userGroup: 'User/Group',
user: 'User',
uGroup: 'Group',
},
container: {
createContainer: 'Create container',
@ -1181,6 +1178,21 @@ const message = {
'Some programs need to specify a secondary directory as the running directory, such as ThinkPHP5, Laravel',
runUserHelper:
'For websites deployed through the PHP runtime environment, all files, folder owners, and user groups under the index and subdirectories need to be set to 1000, command: chown -R 1000:1000 index',
userGroup: 'User/Group',
user: 'User',
uGroup: 'Group',
proxyPath: 'Proxy Path',
proxyPass: 'Target URL',
cache: 'Cache',
status: 'Status',
createProxy: 'Create reverse proxy',
editProxy: 'Edit reverse proxy',
cacheTime: 'Cache time',
enableCache: 'Open cache',
proxyHost: 'Send domain name',
disabled: 'Stopped',
startProxy: 'Start Reverse proxy',
stopProxy: 'Stop the Reverse proxy',
},
php: {
short_open_tag: 'Short tag support',

View File

@ -1183,7 +1183,6 @@ const message = {
userGroup: '运行用户/',
user: '用户',
uGroup: '用户组',
addProxy: '添加反向代理',
proxyPath: '代理目录',
proxyPass: '目标URL',
cache: '缓存',
@ -1194,6 +1193,8 @@ const message = {
enableCache: '开启缓存',
proxyHost: '发送域名',
disabled: '已停止',
startProxy: '开启反向代理',
stopProxy: '关闭反向代理',
},
php: {
short_open_tag: '短标签支持',

View File

@ -1,24 +1,24 @@
<template>
<el-drawer v-model="open" :close-on-click-modal="false" size="40%" :before-close="handleClose">
<template #header>
<DrawerHeader :header="$t('website.createProxy')" :back="handleClose" />
<DrawerHeader :header="$t('website.' + proxy.operate + 'Proxy')" :back="handleClose" />
</template>
<el-row v-loading="loading">
<el-col :span="22" :offset="1">
<el-form ref="proxyForm" label-position="top" :model="proxy" :rules="rules">
<el-form-item :label="$t('commons.table.name')" prop="name">
<el-input v-model.trim="proxy.name"></el-input>
<el-input v-model.trim="proxy.name" :disabled="proxy.operate === 'edit'"></el-input>
</el-form-item>
<el-form-item :label="$t('website.proxyPath')" prop="match">
<el-input v-model.trim="proxy.match"></el-input>
</el-form-item>
<el-form-item :label="$t('website.enableCache')" prop="cache">
<el-switch v-model="proxy.cache"></el-switch>
<el-switch v-model="proxy.cache" @change="changeCache(proxy.cache)"></el-switch>
</el-form-item>
<el-form-item :label="$t('website.cacheTime')" prop="cacheTime" v-if="proxy.cache">
<el-input v-model.number="proxy.cacheTime" maxlength="15">
<template #append>
<el-select v-model="proxy.cacheUnit" style="width: 80px">
<el-select v-model="proxy.cacheUnit" style="width: 100px">
<el-option
v-for="(unit, index) in Units"
:key="index"
@ -65,7 +65,6 @@ import { ref } from 'vue';
import { MsgSuccess } from '@/utils/message';
import { Website } from '@/api/interface/website';
import { Units } from '@/global/mimetype';
// import { Website } from '@/api/interface/website';
const proxyForm = ref<FormInstance>();
const rules = ref({
@ -103,9 +102,20 @@ const handleClose = () => {
const acceptParams = async (proxyParam: Website.ProxyConfig) => {
proxy.value = proxyParam;
console.log(proxy.value);
open.value = true;
};
const changeCache = (cache: boolean) => {
if (cache) {
proxy.value.cacheTime = 1;
proxy.value.cacheUnit = 'm';
} else {
proxy.value.cacheTime = 0;
proxy.value.cacheUnit = '';
}
};
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {
@ -115,7 +125,11 @@ const submit = async (formEl: FormInstance | undefined) => {
loading.value = true;
CreateProxyConfig(proxy.value)
.then(() => {
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
if (proxy.value.operate == 'create') {
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
} else {
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
}
handleClose();
})
.finally(() => {

View File

@ -1,36 +1,46 @@
<template>
<ComplexTable :data="data" @search="search" v-loading="loading">
<template #toolbar>
<el-button type="primary" plain @click="openCreate">{{ $t('website.addProxy') }}</el-button>
<el-button type="primary" plain @click="openCreate">{{ $t('website.createProxy') }}</el-button>
</template>
<el-table-column :label="$t('commons.table.name')" prop="name"></el-table-column>
<el-table-column :label="$t('website.proxyPath')" prop="match"></el-table-column>
<el-table-column :label="$t('website.proxyPass')" prop="proxyPass"></el-table-column>
<el-table-column :label="$t('website.cache')" prop="cache">
<template #default="{ row }">
<el-switch v-model="row.cache"></el-switch>
<el-switch v-model="row.cache" @change="changeCache(row)"></el-switch>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="enable">
<template #default="{ row }">
<el-button v-if="row.enable" link type="success" :icon="VideoPlay">
<el-button v-if="row.enable" link type="success" :icon="VideoPlay" @click="opProxy(row)">
{{ $t('commons.status.running') }}
</el-button>
<el-button v-else link type="danger" :icon="VideoPause">
<el-button v-else link type="danger" :icon="VideoPause" @click="opProxy(row)">
{{ $t('commons.status.stopped') }}
</el-button>
</template>
</el-table-column>
<fu-table-operations
:ellipsis="10"
width="260px"
:buttons="buttons"
:label="$t('commons.table.operate')"
fixed="right"
fix
/>
</ComplexTable>
<Create ref="createRef" @close="search()" />
</template>
<script lang="ts" setup name="proxy">
import { Website } from '@/api/interface/website';
import { GetProxyConfig } from '@/api/modules/website';
import { CreateProxyConfig, GetProxyConfig } from '@/api/modules/website';
import { computed, onMounted, ref } from 'vue';
import Create from './create/index.vue';
import { VideoPlay, VideoPause } from '@element-plus/icons-vue';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
const props = defineProps({
id: {
@ -45,6 +55,15 @@ const loading = ref(false);
const data = ref();
const createRef = ref();
const buttons = [
{
label: i18n.global.t('commons.button.edit'),
click: function (row: Website.ProxyConfig) {
openEdit(row);
},
},
];
const initData = (id: number): Website.ProxyConfig => ({
id: id,
operate: 'create',
@ -62,6 +81,56 @@ const initData = (id: number): Website.ProxyConfig => ({
const openCreate = () => {
createRef.value.acceptParams(initData(id.value));
};
const openEdit = (proxyConfig: Website.ProxyConfig) => {
let proxy = JSON.parse(JSON.stringify(proxyConfig));
proxy.operate = 'edit';
createRef.value.acceptParams(proxy);
};
const changeCache = (proxyConfig: Website.ProxyConfig) => {
proxyConfig.operate = 'edit';
if (proxyConfig.cache) {
proxyConfig.cacheTime = 1;
proxyConfig.cacheUnit = 'm';
}
submit(proxyConfig);
};
const submit = async (proxyConfig: Website.ProxyConfig) => {
loading.value = true;
CreateProxyConfig(proxyConfig)
.then(() => {
MsgSuccess(i18n.global.t('commons.msg.updateSuccess'));
search();
})
.finally(() => {
loading.value = false;
});
};
const opProxy = (proxyConfig: Website.ProxyConfig) => {
let proxy = JSON.parse(JSON.stringify(proxyConfig));
proxy.enable = !proxyConfig.enable;
let message = '';
if (proxy.enable) {
proxy.operate = 'enable';
message = i18n.global.t('website.startProxy');
} else {
proxy.operate = 'disable';
message = i18n.global.t('website.stopProxy');
}
ElMessageBox.confirm(message, i18n.global.t('cronjob.changeStatus'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
})
.then(async () => {
await submit(proxy);
search();
})
.catch(() => {});
};
const search = async () => {
try {
loading.value = true;

View File

@ -39,7 +39,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
host: '0.0.0.0',
proxy: {
'/api/v1': {
target: 'http://localhost:9999/',
target: 'http://192.168.1.15:9999/',
changeOrigin: true,
ws: true,
},