mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-18 19:36:21 +08:00
feat: Complete the Docker proxy synchronization function (#8480)
This commit is contained in:
parent
f485b1729c
commit
4aa628121c
13 changed files with 55 additions and 112 deletions
|
@ -151,6 +151,7 @@ type ProxyUpdate struct {
|
|||
ProxyUser string `json:"proxyUser"`
|
||||
ProxyPasswd string `json:"proxyPasswd"`
|
||||
ProxyPasswdKeep string `json:"proxyPasswdKeep"`
|
||||
ProxyDocker bool `json:"proxyDocker"`
|
||||
}
|
||||
|
||||
type CleanData struct {
|
||||
|
|
|
@ -199,6 +199,9 @@ func (u *SettingService) UpdateProxy(req dto.ProxyUpdate) error {
|
|||
if err := settingRepo.Update("ProxyPasswdKeep", req.ProxyPasswdKeep); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := xpack.ProxyDocker(loadDockerProxy(req)); err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
if err := xpack.Sync(constant.SyncSystemProxy); err != nil {
|
||||
global.LOG.Errorf("sync proxy to node failed, err: %v", err)
|
||||
|
@ -636,3 +639,18 @@ func (u *SettingService) GetLoginSetting() (*dto.SystemSetting, error) {
|
|||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func loadDockerProxy(req dto.ProxyUpdate) string {
|
||||
if len(req.ProxyType) == 0 || req.ProxyType == "close" || !req.ProxyDocker {
|
||||
return ""
|
||||
}
|
||||
proxyPasswd := ""
|
||||
if len(req.ProxyUser) != 0 {
|
||||
proxyPasswd = req.ProxyPasswd + "@"
|
||||
}
|
||||
proxyUrl := req.ProxyType + "://" + req.ProxyUser + ":" + proxyPasswd + req.ProxyUrl + req.ProxyPort
|
||||
if req.ProxyType == "http" || req.ProxyType == "https" {
|
||||
req.ProxyUrl = req.ProxyType + "://" + req.ProxyUrl
|
||||
}
|
||||
return proxyUrl
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ const (
|
|||
const (
|
||||
SyncSystemProxy = "SyncSystemProxy"
|
||||
SyncBackupAccounts = "SyncBackupAccounts"
|
||||
SyncAlertSetting = "SyncAlertSetting"
|
||||
)
|
||||
|
||||
var WebUrlMap = map[string]struct{}{
|
||||
|
|
|
@ -14,6 +14,8 @@ import (
|
|||
|
||||
func Proxy(c *gin.Context, currentNode string) {}
|
||||
|
||||
func ProxyDocker(proxyURL string) error { return nil }
|
||||
|
||||
func UpdateGroup(name string, group, newGroup uint) error { return nil }
|
||||
|
||||
func CheckBackupUsed(name string) error { return nil }
|
||||
|
|
|
@ -3265,8 +3265,9 @@ const message = {
|
|||
nodeInfo: 'Node Information',
|
||||
syncInfo: 'Data synchronization',
|
||||
syncHelper: 'When master node data changes, it synchronizes to this child node in real-time',
|
||||
syncBackupAccount: 'Backup account data',
|
||||
syncProxy: 'System proxy data',
|
||||
syncBackupAccount: 'Backup account settings',
|
||||
syncProxy: 'System proxy settings',
|
||||
syncAlertSetting: 'System alert settings',
|
||||
syncNodeInfo: 'Node basic data,',
|
||||
nodeSyncHelper: 'Node information synchronization will sync the following information:',
|
||||
nodeSyncHelper1: '1. Public backup account information',
|
||||
|
|
|
@ -3124,8 +3124,9 @@ const message = {
|
|||
nodeInfo: 'ノード情報',
|
||||
syncInfo: 'データ同期,',
|
||||
syncHelper: 'マスターノードのデータが変更されると、この子ノードにリアルタイムで同期されます,',
|
||||
syncBackupAccount: 'アカウントデータのバックアップ,',
|
||||
syncProxy: 'システムプロキシデータ,',
|
||||
syncBackupAccount: 'バックアップアカウント設定',
|
||||
syncProxy: 'システムプロキシ設定',
|
||||
syncAlertSetting: 'システムアラート設定',
|
||||
syncNodeInfo: 'ノード基本データ,',
|
||||
nodeSyncHelper: 'ノード情報の同期は、以下の情報を同期します:',
|
||||
nodeSyncHelper1: '1. 公共のバックアップアカウント情報',
|
||||
|
|
|
@ -3072,8 +3072,9 @@ const message = {
|
|||
nodeInfo: '노드 정보',
|
||||
syncInfo: '데이터 동기화,',
|
||||
syncHelper: '마스터 노드 데이터가 변경되면, 이 자식 노드에 실시간으로 동기화됩니다,',
|
||||
syncBackupAccount: '계정 데이터 백업,',
|
||||
syncProxy: '시스템 프록시 데이터,',
|
||||
syncBackupAccount: '백업 계정 설정',
|
||||
syncProxy: '시스템 프록시 설정',
|
||||
syncAlertSetting: '시스템 경고 설정',
|
||||
syncNodeInfo: '노드 기본 데이터,',
|
||||
nodeSyncHelper: '노드 정보 동기화는 다음 정보를 동기화합니다:',
|
||||
nodeSyncHelper1: '1. 공용 백업 계정 정보',
|
||||
|
|
|
@ -3193,8 +3193,9 @@ const message = {
|
|||
nodeInfo: 'Maklumat Nod',
|
||||
syncInfo: 'Penyegerakan data,',
|
||||
syncHelper: 'Apabila data nod induk berubah, ia akan disegerakkan ke nod anak ini secara masa nyata,',
|
||||
syncBackupAccount: 'Data akaun sandaran,',
|
||||
syncProxy: 'Data proksi sistem,',
|
||||
syncBackupAccount: 'Tetapan akaun sandaran',
|
||||
syncProxy: 'Tetapan proksi sistem',
|
||||
syncAlertSetting: 'Tetapan amaran sistem',
|
||||
syncNodeInfo: 'Data asas nod,',
|
||||
nodeSyncHelper: 'Penyelarasan maklumat nod akan menyelaraskan maklumat berikut:',
|
||||
nodeSyncHelper1: '1. Maklumat akaun sandaran awam',
|
||||
|
|
|
@ -3199,8 +3199,9 @@ const message = {
|
|||
nodeInfo: 'Informações do Nó',
|
||||
syncInfo: 'Sincronização de dados,',
|
||||
syncHelper: 'Quando os dados do nó mestre mudam, são sincronizados em tempo real para este nó filho,',
|
||||
syncBackupAccount: 'Dados de conta de backup,',
|
||||
syncProxy: 'Dados de proxy do sistema,',
|
||||
syncBackupAccount: 'Configurações de conta de backup',
|
||||
syncProxy: 'Configurações de proxy do sistema',
|
||||
syncAlertSetting: 'Configurações de alerta do sistema',
|
||||
syncNodeInfo: 'Dados básicos do nó,',
|
||||
nodeSyncHelper: 'A sincronização das informações do nó irá sincronizar as seguintes informações:',
|
||||
nodeSyncHelper1: '1. Informações da conta de backup pública',
|
||||
|
|
|
@ -3188,8 +3188,9 @@ const message = {
|
|||
syncInfo: 'Синхронизация данных,',
|
||||
syncHelper:
|
||||
'При изменении данных главного узла, происходит синхронизация с этим дочерним узлом в реальном времени,',
|
||||
syncBackupAccount: 'Резервные данные аккаунта,',
|
||||
syncProxy: 'Данные системного прокси,',
|
||||
syncBackupAccount: 'Настройки резервной учётной записи',
|
||||
syncProxy: 'Настройки системного прокси',
|
||||
syncAlertSetting: 'Настройки системных предупреждений',
|
||||
syncNodeInfo: 'Базовые данные узла,',
|
||||
nodeSyncHelper: 'Синхронизация информации о узле будет синхронизировать следующую информацию:',
|
||||
nodeSyncHelper1: '1. Информация о публичной резервной учетной записи',
|
||||
|
|
|
@ -3028,8 +3028,9 @@ const message = {
|
|||
nodeInfo: '節點資訊',
|
||||
syncInfo: '數據同步,',
|
||||
syncHelper: '當主節點數據發生變化時,實時同步到該子節點,',
|
||||
syncBackupAccount: '備份帳號數據,',
|
||||
syncProxy: '系統代理數據,',
|
||||
syncBackupAccount: '備份帳號設定',
|
||||
syncProxy: '系統代理設定',
|
||||
syncAlertSetting: '系統告警設定',
|
||||
syncNodeInfo: '節點基礎數據,',
|
||||
nodeSyncHelper: '節點信息同步將同步以下信息:',
|
||||
nodeSyncHelper1: '1. 公用的備份帳號信息',
|
||||
|
|
|
@ -3011,8 +3011,9 @@ const message = {
|
|||
nodeInfo: '节点信息',
|
||||
syncInfo: '数据同步',
|
||||
syncHelper: '主节点数据发生变化时,实时同步到该子节点',
|
||||
syncBackupAccount: '备份账号数据',
|
||||
syncProxy: '系统代理数据',
|
||||
syncBackupAccount: '备份账号设置',
|
||||
syncProxy: '系统代理设置',
|
||||
syncAlertSetting: '系统告警设置',
|
||||
syncNodeInfo: '节点基础数据',
|
||||
nodeSyncHelper: '节点信息同步将同步以下信息:',
|
||||
nodeSyncHelper1: '1. 公用的备份账号信息',
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<DrawerPro v-model="passwordVisible" :header="$t('setting.proxy')" @close="handleClose" size="large">
|
||||
<DrawerPro v-model="proxyVisible" :header="$t('setting.proxy')" @close="handleClose" size="large">
|
||||
<el-form ref="formRef" label-position="top" :model="form" :rules="rules" v-loading="loading">
|
||||
<el-alert class="common-prompt" :closable="false" type="warning">
|
||||
<template #default>
|
||||
|
@ -46,45 +46,13 @@
|
|||
<el-checkbox v-model="form.proxyPasswdKeepItem" :label="$t('setting.proxyPasswdKeep')" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="isMasterProductPro">
|
||||
<el-checkbox v-model="form.proxyDocker" @change="onChange" :label="$t('setting.proxyDocker')" />
|
||||
<el-checkbox v-model="form.proxyDocker" :label="$t('setting.proxyDocker')" />
|
||||
<span class="input-help">{{ $t('setting.proxyDockerHelper') }}</span>
|
||||
</el-form-item>
|
||||
<div v-if="form.proxyDocker">
|
||||
<el-form-item prop="syncToNode">
|
||||
<el-switch
|
||||
@change="getNodes"
|
||||
v-model="form.syncToNode"
|
||||
active-value="Enable"
|
||||
inactive-value="Disable"
|
||||
></el-switch>
|
||||
<span class="ml-2.5 el-checkbox">{{ $t('setting.syncToNode') }}</span>
|
||||
<span class="input-help">{{ $t('setting.syncToNodeHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('setting.nodes')" prop="nodes" v-if="form.syncToNode === 'Enable'">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-select v-model="form.selectNode" class="p-w-200">
|
||||
<el-option :label="$t('commons.table.all')" value="all"></el-option>
|
||||
<el-option :label="$t('setting.selectNode')" value="select"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="12" v-if="form.selectNode === 'select'">
|
||||
<el-select v-model="form.nodes" multiple class="p-w-200">
|
||||
<el-option
|
||||
v-for="item in nodeList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button :disabled="loading" @click="passwordVisible = false">
|
||||
<el-button :disabled="loading" @click="proxyVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="submitChangePassword(formRef)">
|
||||
|
@ -102,13 +70,10 @@ import i18n from '@/lang';
|
|||
import { MsgSuccess } from '@/utils/message';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { listNodeOptions, updateProxy } from '@/api/modules/setting';
|
||||
import { updateProxy } from '@/api/modules/setting';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { updateDaemonJson } from '@/api/modules/container';
|
||||
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
|
||||
import { escapeProxyURL } from '@/utils/util';
|
||||
import { updateDockerProxySetting } from '@/xpack/api/modules/setting';
|
||||
|
||||
const globalStore = GlobalStore();
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
@ -123,8 +88,7 @@ const rules = reactive({
|
|||
});
|
||||
|
||||
const loading = ref(false);
|
||||
const passwordVisible = ref<boolean>(false);
|
||||
const proxyDockerVisible = ref<boolean>(false);
|
||||
const proxyVisible = ref<boolean>(false);
|
||||
const form = reactive({
|
||||
proxyUrl: '',
|
||||
proxyType: '',
|
||||
|
@ -135,11 +99,7 @@ const form = reactive({
|
|||
proxyPasswdKeep: '',
|
||||
proxyPasswdKeepItem: false,
|
||||
proxyDocker: false,
|
||||
syncToNode: 'Enable',
|
||||
selectNode: 'all',
|
||||
nodes: [],
|
||||
});
|
||||
const nodeList = ref([]);
|
||||
|
||||
interface DialogProps {
|
||||
url: string;
|
||||
|
@ -149,8 +109,6 @@ interface DialogProps {
|
|||
passwd: string;
|
||||
passwdKeep: string;
|
||||
proxyDocker: string;
|
||||
proxyDockerSyncToNode: string;
|
||||
proxyDockerSyncNodes: string;
|
||||
}
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
if (params.url) {
|
||||
|
@ -167,24 +125,11 @@ const acceptParams = (params: DialogProps): void => {
|
|||
form.proxyUser = params.user;
|
||||
form.proxyPasswd = params.passwd;
|
||||
form.proxyDocker = params.proxyDocker !== '';
|
||||
if (form.proxyDocker) {
|
||||
getNodes();
|
||||
form.syncToNode = params.proxyDockerSyncToNode;
|
||||
form.nodes = params.proxyDockerSyncNodes ? JSON.parse(params.proxyDockerSyncNodes) : [];
|
||||
form.selectNode = form.nodes.length > 0 ? 'select' : 'all';
|
||||
}
|
||||
|
||||
proxyDockerVisible.value = params.proxyDocker !== '';
|
||||
passwordVisible.value = true;
|
||||
proxyVisible.value = true;
|
||||
form.proxyPasswdKeepItem = params.passwdKeep === 'Enable';
|
||||
};
|
||||
|
||||
const getNodes = () => {
|
||||
if (form.syncToNode === 'Enable' && nodeList.value.length === 0) {
|
||||
listNodes();
|
||||
}
|
||||
};
|
||||
|
||||
const submitChangePassword = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
|
@ -205,13 +150,7 @@ const submitChangePassword = async (formEl: FormInstance | undefined) => {
|
|||
if (form.proxyType === 'http' || form.proxyType === 'https') {
|
||||
params.proxyUrl = form.proxyType + '://' + form.proxyUrl;
|
||||
}
|
||||
if (
|
||||
isMasterProductPro.value &&
|
||||
(params.proxyDocker ||
|
||||
(proxyDockerVisible.value && isClose) ||
|
||||
(proxyDockerVisible.value && !isClose) ||
|
||||
(proxyDockerVisible.value && !params.proxyDocker))
|
||||
) {
|
||||
if (isMasterProductPro.value && params.proxyDocker) {
|
||||
let confirmParams = {
|
||||
header: i18n.global.t('setting.confDockerProxy'),
|
||||
operationInfo: i18n.global.t('setting.restartNowHelper'),
|
||||
|
@ -224,10 +163,7 @@ const submitChangePassword = async (formEl: FormInstance | undefined) => {
|
|||
.then(async () => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
passwordVisible.value = false;
|
||||
if (isClose) {
|
||||
await updateDaemonJson(`${form.proxyType}-proxy`, '');
|
||||
}
|
||||
proxyVisible.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
|
@ -253,26 +189,10 @@ const onSubmit = async () => {
|
|||
if (!isClose) {
|
||||
params.proxyPasswdKeep = form.proxyPasswdKeepItem ? 'Enable' : 'Disable';
|
||||
}
|
||||
let proxyPort = params.proxyPort ? `:${params.proxyPort}` : '';
|
||||
let proxyUser = params.proxyUser ? `${escapeProxyURL(params.proxyUser)}` : '';
|
||||
let proxyPasswd = '';
|
||||
if (params.proxyUser) {
|
||||
proxyPasswd = params.proxyPasswd ? `:${escapeProxyURL(params.proxyPasswd)}@` : '@';
|
||||
}
|
||||
let proxyUrl = form.proxyType + '://' + proxyUser + proxyPasswd + form.proxyUrl + proxyPort;
|
||||
if (form.proxyType === 'http' || form.proxyType === 'https') {
|
||||
params.proxyUrl = form.proxyType + '://' + form.proxyUrl;
|
||||
}
|
||||
await updateProxy(params);
|
||||
if (isClose || params.proxyDocker === false) {
|
||||
proxyUrl = '';
|
||||
}
|
||||
let param = {
|
||||
proxyDocker: proxyUrl,
|
||||
proxyDockerSyncToNode: form.syncToNode,
|
||||
proxyDockerSyncNodes: JSON.stringify(form.nodes),
|
||||
};
|
||||
await updateDockerProxySetting(param);
|
||||
emit('search');
|
||||
handleClose();
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
|
@ -281,15 +201,8 @@ const onSubmit = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
const listNodes = async () => {
|
||||
try {
|
||||
const res = await listNodeOptions();
|
||||
nodeList.value = res.data || [];
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
passwordVisible.value = false;
|
||||
proxyVisible.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
|
|
Loading…
Add table
Reference in a new issue