mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-18 22:22:59 +08:00
feat: 增加反向代理类型
This commit is contained in:
parent
6260281cac
commit
b7d55801cd
@ -100,7 +100,7 @@ func (b *BaseApi) RecoverWebsite(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteWebSite(c *gin.Context) {
|
||||
var req dto.WebSiteDel
|
||||
var req request.WebSiteDel
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
|
@ -21,6 +21,7 @@ type WebSiteCreate struct {
|
||||
Alias string `json:"alias" validate:"required"`
|
||||
Remark string `json:"remark"`
|
||||
OtherDomains string `json:"otherDomains"`
|
||||
Proxy string `json:"proxy"`
|
||||
AppType AppType `json:"appType"`
|
||||
AppInstall NewAppInstall `json:"appInstall"`
|
||||
AppID uint `json:"appID"`
|
||||
@ -45,12 +46,6 @@ type NewAppInstall struct {
|
||||
Params map[string]interface{} `json:"params"`
|
||||
}
|
||||
|
||||
type WebSiteDel struct {
|
||||
ID uint `json:"id"`
|
||||
DeleteApp bool `json:"deleteApp"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
}
|
||||
|
||||
type WebSiteRecover struct {
|
||||
WebsiteName string `json:"websiteName" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
|
@ -14,6 +14,7 @@ type WebSite struct {
|
||||
AppInstallID uint `gorm:"type:integer" json:"appInstallId"`
|
||||
WebSiteGroupID uint `gorm:"type:integer" json:"webSiteGroupId"`
|
||||
WebSiteSSLID uint `gorm:"type:integer" json:"webSiteSSLId"`
|
||||
Proxy string `gorm:"type:varchar(128);not null" json:"proxy"`
|
||||
Domains []WebSiteDomain `json:"domains"`
|
||||
WebSiteSSL WebSiteSSL `json:"webSiteSSL"`
|
||||
}
|
||||
|
@ -11,3 +11,10 @@ type WebsiteWafUpdate struct {
|
||||
Key string `json:"key" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
}
|
||||
|
||||
type WebSiteDel struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
DeleteApp bool `json:"deleteApp"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ type IWebsiteService interface {
|
||||
Recover(req dto.WebSiteRecover) error
|
||||
RecoverByUpload(req dto.WebSiteRecoverByFile) error
|
||||
UpdateWebsite(req dto.WebSiteUpdate) error
|
||||
DeleteWebSite(req dto.WebSiteDel) error
|
||||
DeleteWebSite(req request.WebSiteDel) error
|
||||
GetWebsite(id uint) (dto.WebsiteDTO, error)
|
||||
CreateWebsiteDomain(create dto.WebSiteDomainCreate) (model.WebSiteDomain, error)
|
||||
GetWebsiteDomain(websiteId uint) ([]model.WebSiteDomain, error)
|
||||
@ -88,9 +88,11 @@ func (w WebsiteService) CreateWebsite(create dto.WebSiteCreate) error {
|
||||
AppInstallID: create.AppInstallID,
|
||||
WebSiteGroupID: create.WebSiteGroupID,
|
||||
Protocol: constant.ProtocolHTTP,
|
||||
Proxy: create.Proxy,
|
||||
}
|
||||
|
||||
if create.Type == "deployment" {
|
||||
switch create.Type {
|
||||
case constant.Deployment:
|
||||
if create.AppType == dto.NewApp {
|
||||
install, err := ServiceGroupApp.Install(create.AppInstall.Name, create.AppInstall.AppDetailId, create.AppInstall.Params)
|
||||
if err != nil {
|
||||
@ -98,7 +100,7 @@ func (w WebsiteService) CreateWebsite(create dto.WebSiteCreate) error {
|
||||
}
|
||||
website.AppInstallID = install.ID
|
||||
}
|
||||
} else {
|
||||
case constant.Static:
|
||||
if err := createStaticHtml(website); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -240,12 +242,12 @@ func (w WebsiteService) GetWebsite(id uint) (dto.WebsiteDTO, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (w WebsiteService) DeleteWebSite(req dto.WebSiteDel) error {
|
||||
func (w WebsiteService) DeleteWebSite(req request.WebSiteDel) error {
|
||||
website, err := websiteRepo.GetFirst(commonRepo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := delNginxConfig(website); err != nil {
|
||||
if err := delNginxConfig(website, req.ForceDelete); err != nil {
|
||||
return err
|
||||
}
|
||||
tx, ctx := getTxAndContext()
|
||||
@ -253,7 +255,7 @@ func (w WebsiteService) DeleteWebSite(req dto.WebSiteDel) error {
|
||||
if req.DeleteApp {
|
||||
websites, _ := websiteRepo.GetBy(websiteRepo.WithAppInstallId(website.AppInstallID))
|
||||
if len(websites) > 1 {
|
||||
return errors.New("other website use this app")
|
||||
return buserr.New(constant.ErrAppDelete)
|
||||
}
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
|
@ -74,7 +74,6 @@ func createStaticHtml(website *model.WebSite) error {
|
||||
}
|
||||
|
||||
func createWebsiteFolder(nginxInstall model.AppInstall, website *model.WebSite) error {
|
||||
|
||||
nginxFolder := path.Join(constant.AppInstallDir, "nginx", nginxInstall.Name)
|
||||
siteFolder := path.Join(nginxFolder, "www", "sites", website.Alias)
|
||||
fileOp := files.NewFileOp()
|
||||
@ -99,7 +98,6 @@ func createWebsiteFolder(nginxInstall model.AppInstall, website *model.WebSite)
|
||||
}
|
||||
|
||||
func configDefaultNginx(website *model.WebSite, domains []model.WebSiteDomain) error {
|
||||
|
||||
nginxInstall, err := getAppInstallByKey("nginx")
|
||||
if err != nil {
|
||||
return err
|
||||
@ -131,16 +129,19 @@ func configDefaultNginx(website *model.WebSite, domains []model.WebSiteDomain) e
|
||||
server.UpdateDirective("set", []string{"$RulePath", path.Join(siteFolder, "waf", "rules")})
|
||||
server.UpdateDirective("set", []string{"$logdir", path.Join(siteFolder, "log")})
|
||||
|
||||
if website.Type == "deployment" {
|
||||
switch website.Type {
|
||||
case constant.Deployment:
|
||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proxy := fmt.Sprintf("http://127.0.0.1:%d", appInstall.HttpPort)
|
||||
server.UpdateRootProxy([]string{proxy})
|
||||
} else {
|
||||
case constant.Static:
|
||||
server.UpdateRoot(path.Join("/www/sites", website.Alias))
|
||||
server.UpdateRootLocation()
|
||||
case constant.Proxy:
|
||||
server.UpdateRootProxy([]string{website.Proxy})
|
||||
}
|
||||
|
||||
config.FilePath = configPath
|
||||
@ -154,8 +155,7 @@ func configDefaultNginx(website *model.WebSite, domains []model.WebSiteDomain) e
|
||||
return opNginx(nginxInstall.ContainerName, constant.NginxReload)
|
||||
}
|
||||
|
||||
func delNginxConfig(website model.WebSite) error {
|
||||
|
||||
func delNginxConfig(website model.WebSite, force bool) error {
|
||||
nginxApp, err := appRepo.GetFirst(appRepo.WithKey("nginx"))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -178,11 +178,16 @@ func delNginxConfig(website model.WebSite) error {
|
||||
if err := fileOp.DeleteFile(configPath); err != nil {
|
||||
return err
|
||||
}
|
||||
return opNginx(nginxInstall.ContainerName, "reload")
|
||||
if err := opNginx(nginxInstall.ContainerName, "reload"); err != nil {
|
||||
if force {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addListenAndServerName(website model.WebSite, ports []int, domains []string) error {
|
||||
|
||||
nginxFull, err := getNginxFull(&website)
|
||||
if err != nil {
|
||||
return nil
|
||||
@ -203,7 +208,6 @@ func addListenAndServerName(website model.WebSite, ports []int, domains []string
|
||||
}
|
||||
|
||||
func deleteListenAndServerName(website model.WebSite, ports []int, domains []string) error {
|
||||
|
||||
nginxFull, err := getNginxFull(&website)
|
||||
if err != nil {
|
||||
return nil
|
||||
@ -280,7 +284,6 @@ func createPemFile(website model.WebSite, websiteSSL model.WebSiteSSL) error {
|
||||
}
|
||||
|
||||
func applySSL(website model.WebSite, websiteSSL model.WebSiteSSL) error {
|
||||
|
||||
nginxFull, err := getNginxFull(&website)
|
||||
if err != nil {
|
||||
return nil
|
||||
@ -398,7 +401,7 @@ func handleWebsiteBackup(backupType, baseDir, backupDir, domain, backupName stri
|
||||
return err
|
||||
}
|
||||
|
||||
if website.Type == "deployment" {
|
||||
if website.Type == constant.Deployment {
|
||||
if err := mysqlOpration(&website, "backup", tmpDir); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -451,7 +454,7 @@ func handleWebsiteRecover(website *model.WebSite, fileDir string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if website.Type == "deployment" {
|
||||
if website.Type == constant.Deployment {
|
||||
if err := mysqlOpration(website, "recover", fileDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ var (
|
||||
var (
|
||||
ErrDomainIsExist = "ErrDomainIsExist"
|
||||
ErrAliasIsExist = "ErrAliasIsExist"
|
||||
ErrAppDelete = "ErrAppDelete"
|
||||
)
|
||||
|
||||
//ssl
|
||||
|
@ -14,3 +14,9 @@ const (
|
||||
ProtocolHTTP = "HTTP"
|
||||
ProtocolHTTPS = "HTTPS"
|
||||
)
|
||||
|
||||
const (
|
||||
Deployment = "deployment"
|
||||
Static = "static"
|
||||
Proxy = "proxy"
|
||||
)
|
||||
|
@ -30,6 +30,7 @@ ErrFileToLarge: "file is too large"
|
||||
#website
|
||||
ErrDomainIsExist: "Domain is already exist"
|
||||
ErrAliasIsExist: "Alias is already exist"
|
||||
ErrAppDelete: 'Other Website use this App'
|
||||
|
||||
#ssl
|
||||
ErrSSLCannotDelete: "The certificate is being used by the website and cannot be removed"
|
||||
|
@ -29,7 +29,7 @@ ErrFileToLarge: "文件超过10M,无法打开"
|
||||
#website
|
||||
ErrDomainIsExist: "域名已存在"
|
||||
ErrAliasIsExist: "代号已存在"
|
||||
ErrAppDelete: ''
|
||||
ErrAppDelete: '其他网站使用此应用,不能删除'
|
||||
|
||||
#ssl
|
||||
ErrSSLCannotDelete: "证书正在被网站使用,无法删除"
|
||||
|
@ -54,6 +54,7 @@ export namespace WebSite {
|
||||
id: number;
|
||||
deleteApp: boolean;
|
||||
deleteBackup: boolean;
|
||||
forceDelete: boolean;
|
||||
}
|
||||
|
||||
export interface WebSiteCreateReq {
|
||||
@ -65,6 +66,7 @@ export namespace WebSite {
|
||||
appInstallId: number;
|
||||
webSiteGroupId: number;
|
||||
otherDomains: string;
|
||||
proxy: string;
|
||||
}
|
||||
|
||||
export interface WebSiteUpdateReq {
|
||||
|
@ -104,7 +104,7 @@ export default {
|
||||
imageName: '支持英文、中文、数字、:.-_,长度1-30',
|
||||
complexityPassword: '请输入 8 位以上、必须含有字母、数字、特殊符号的密码',
|
||||
commonPassword: '请输入 6 位以上长度密码',
|
||||
linuxName: '支持英文、数字、.-_,长度1-30',
|
||||
linuxName: '支持英文、数字、._,长度1-30',
|
||||
email: '请输入正确的邮箱',
|
||||
number: '请输入正确的数字',
|
||||
ip: '请输入正确的 IP 地址',
|
||||
@ -786,7 +786,7 @@ export default {
|
||||
otherDomains: '其他域名',
|
||||
type: '类型',
|
||||
static: '静态网站',
|
||||
deployment: '反向代理',
|
||||
deployment: '一键部署',
|
||||
supportUpType: '仅支持 tar.gz 文件',
|
||||
zipFormat: 'tar.gz 压缩包结构:test.tar.gz 压缩包内,必需包含 website.json 文件',
|
||||
proxy: '反向代理',
|
||||
@ -868,6 +868,9 @@ export default {
|
||||
fileExtBlock: '文件扩展名黑名单',
|
||||
value: '值',
|
||||
enable: '开启',
|
||||
proxyAddress: '代理地址',
|
||||
proxyHelper: '例如: http://127.0.0.1:8080',
|
||||
forceDelete: '强制删除',
|
||||
},
|
||||
nginx: {
|
||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||
|
@ -1,17 +1,24 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:title="$t('website.create')"
|
||||
width="40%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<el-form ref="websiteForm" label-position="right" :model="website" label-width="130px" :rules="rules">
|
||||
<el-form
|
||||
ref="websiteForm"
|
||||
label-position="right"
|
||||
:model="website"
|
||||
label-width="130px"
|
||||
:rules="rules"
|
||||
:validate-on-rule-change="false"
|
||||
>
|
||||
<el-form-item :label="$t('website.type')" prop="type">
|
||||
<el-select v-model="website.type">
|
||||
<el-option :label="$t('website.deployment')" value="deployment"></el-option>
|
||||
<el-option :label="$t('website.static')" value="static"></el-option>
|
||||
<el-option :label="$t('website.proxy')" value="proxy"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.group')" prop="webSiteGroupId">
|
||||
@ -103,6 +110,9 @@
|
||||
<el-form-item :label="$t('website.alias')" prop="alias">
|
||||
<el-input v-model="website.alias" :placeholder="$t('website.aliasHelper')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="website.type === 'proxy'" :label="$t('website.proxyAddress')" prop="proxy">
|
||||
<el-input v-model="website.proxy" :placeholder="$t('website.proxyHelper')"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.remark')" prop="remark">
|
||||
<el-input v-model="website.remark"></el-input>
|
||||
</el-form-item>
|
||||
@ -141,6 +151,7 @@ const website = ref({
|
||||
appInstallId: undefined,
|
||||
webSiteGroupId: 1,
|
||||
otherDomains: '',
|
||||
proxy: '',
|
||||
appinstall: {
|
||||
appId: 0,
|
||||
name: '',
|
||||
@ -149,15 +160,16 @@ const website = ref({
|
||||
version: '',
|
||||
},
|
||||
});
|
||||
let rules = ref({
|
||||
let rules = reactive({
|
||||
primaryDomain: [Rules.linuxName],
|
||||
alias: [Rules.linuxName],
|
||||
type: [Rules.requiredInput],
|
||||
webSiteGroupId: [Rules.requiredSelectBusiness],
|
||||
appInstallId: [Rules.requiredSelectBusiness],
|
||||
appType: [Rules.requiredInput],
|
||||
proxy: [Rules.requiredInput],
|
||||
appinstall: {
|
||||
name: [Rules.requiredInput],
|
||||
name: [Rules.linuxName],
|
||||
appId: [Rules.requiredSelectBusiness],
|
||||
params: {},
|
||||
},
|
||||
|
@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
:destroy-on-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:title="$t('website.delete')"
|
||||
width="40%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<div style="text-align: center">
|
||||
<el-checkbox v-model="deleteReq.deleteApp" :label="$t('website.deleteApp')" />
|
||||
<div style="text-align: center" :key="key">
|
||||
<el-checkbox v-model="deleteReq.forceDelete" :label="$t('website.forceDelete')" />
|
||||
<el-checkbox v-if="type === 'deployment'" v-model="deleteReq.deleteApp" :label="$t('website.deleteApp')" />
|
||||
<el-checkbox v-model="deleteReq.deleteBackup" :label="$t('website.deleteBackup')" />
|
||||
</div>
|
||||
<template #footer>
|
||||
@ -26,22 +26,19 @@
|
||||
import { DeleteWebsite } from '@/api/modules/website';
|
||||
import i18n from '@/lang';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { reactive, ref } from 'vue';
|
||||
|
||||
// interface DeleteProps {
|
||||
// id: number;
|
||||
// }
|
||||
// const deleteData = ref<DeleteProps>({
|
||||
// id: 0,
|
||||
// });
|
||||
import { ref } from 'vue';
|
||||
import { WebSite } from '@/api/interface/website';
|
||||
|
||||
let key = 1;
|
||||
let open = ref(false);
|
||||
let loading = ref(false);
|
||||
let deleteReq = reactive({
|
||||
let deleteReq = ref({
|
||||
id: 0,
|
||||
deleteApp: false,
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
});
|
||||
let type = ref('');
|
||||
const em = defineEmits(['close']);
|
||||
|
||||
const handleClose = () => {
|
||||
@ -49,14 +46,21 @@ const handleClose = () => {
|
||||
em('close', false);
|
||||
};
|
||||
|
||||
const acceptParams = async (id: number) => {
|
||||
deleteReq.id = id;
|
||||
const acceptParams = async (website: WebSite.WebSite) => {
|
||||
deleteReq.value = {
|
||||
id: 0,
|
||||
deleteApp: false,
|
||||
deleteBackup: false,
|
||||
forceDelete: false,
|
||||
};
|
||||
deleteReq.value.id = website.id;
|
||||
type.value = website.type;
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
loading.value = true;
|
||||
DeleteWebsite(deleteReq)
|
||||
DeleteWebsite(deleteReq.value)
|
||||
.then(() => {
|
||||
handleClose();
|
||||
ElMessage.success(i18n.global.t('commons.msg.deleteSuccess'));
|
||||
|
Loading…
Reference in New Issue
Block a user