feat: support certificate synchronization (#13153)

This commit is contained in:
ssongliu
2026-06-30 18:31:45 +08:00
committed by GitHub
parent 0a1621166e
commit f31f0a89ff
31 changed files with 132 additions and 88 deletions
+1
View File
@@ -135,6 +135,7 @@ type WebsiteSSLPush struct {
PushNode bool `json:"pushNode"`
Nodes string `json:"nodes"`
TaskID string `json:"taskID" validate:"required"`
Sync bool `json:"sync"`
}
type WebsiteCASearch struct {
+30 -29
View File
@@ -104,35 +104,36 @@ type AppDetail struct {
}
type AppInstallDTO struct {
ID uint `json:"id"`
Name string `json:"name"`
AppID uint `json:"appID"`
AppDetailID uint `json:"appDetailID"`
Version string `json:"version"`
Status string `json:"status"`
Message string `json:"message"`
HttpPort int `json:"httpPort"`
HttpsPort int `json:"httpsPort"`
Path string `json:"path"`
CanUpdate bool `json:"canUpdate"`
Icon string `json:"icon"`
AppName string `json:"appName"`
Ready int `json:"ready"`
Total int `json:"total"`
AppKey string `json:"appKey"`
AppType string `json:"appType"`
AppStatus string `json:"appStatus"`
DockerCompose string `json:"dockerCompose"`
WebUI string `json:"webUI"`
CreatedAt time.Time `json:"createdAt"`
Favorite bool `json:"favorite"`
SortOrder int `json:"sortOrder"`
App AppDetail `json:"app"`
Container string `json:"container"`
IsEdit bool `json:"isEdit"`
LinkDB bool `json:"linkDB"`
ResourceKeys []string `json:"resourceKeys"`
ServiceName string `json:"serviceName"`
ID uint `json:"id"`
Name string `json:"name"`
AppID uint `json:"appID"`
AppDetailID uint `json:"appDetailID"`
Version string `json:"version"`
Status string `json:"status"`
Message string `json:"message"`
HttpPort int `json:"httpPort"`
HttpsPort int `json:"httpsPort"`
Path string `json:"path"`
CanUpdate bool `json:"canUpdate"`
Icon string `json:"icon"`
AppName string `json:"appName"`
Ready int `json:"ready"`
Total int `json:"total"`
AppKey string `json:"appKey"`
AppType string `json:"appType"`
AppStatus string `json:"appStatus"`
DockerCompose string `json:"dockerCompose"`
WebUI string `json:"webUI"`
CreatedAt time.Time `json:"createdAt"`
Favorite bool `json:"favorite"`
SortOrder int `json:"sortOrder"`
App AppDetail `json:"app"`
Container string `json:"container"`
IsEdit bool `json:"isEdit"`
LinkDB bool `json:"linkDB"`
ResourceKeys []string `json:"resourceKeys"`
ServiceName string `json:"serviceName"`
Env map[string]interface{} `json:"env"`
}
type AppInstallInfo struct {
+3
View File
@@ -1715,6 +1715,8 @@ func handleInstalled(appInstallList []model.AppInstall, updated, sync, checkUpda
}
resourceKeys := getAppInstallResourceKeys(installed.ID)
envMap := make(map[string]interface{})
_ = json.Unmarshal([]byte(installed.Env), &envMap)
installDTO := response.AppInstallDTO{
ID: installed.ID,
Name: installed.Name,
@@ -1741,6 +1743,7 @@ func handleInstalled(appInstallList []model.AppInstall, updated, sync, checkUpda
Container: installed.ContainerName,
ServiceName: strings.ToLower(installed.ServiceName),
ResourceKeys: resourceKeys,
Env: envMap,
}
if !updated && !checkUpdate {
+4
View File
@@ -974,6 +974,10 @@ func (w WebsiteSSLService) PushToNode(req request.WebsiteSSLPush) error {
websiteSSL.PushNode = pushNode
websiteSSL.Nodes = nodes
if req.Sync {
return xpack.MultiNodeProvider.PushSSLToNode(websiteSSL)
}
pushTask, err := task.NewTaskWithOps(websiteSSL.PrimaryDomain, task.TaskPush, task.TaskScopeWebsite, req.TaskID, websiteSSL.ID)
if err != nil {
return err
+6 -6
View File
@@ -1880,15 +1880,15 @@
},
"/core/xpack/exchange/file": {
"bodyKeys": [
"source",
"dest",
"sourceNode",
"targetNode",
"sourcePath",
"destPath"
"targetPath"
],
"paramKeys": [],
"beforeFunctions": [],
"formatZH": "交换文件 [sourcePath] 到 [destPath]",
"formatEN": "exchange file [sourcePath] to [destPath]"
"formatZH": "交换文件 [sourcePath] 到 [targetPath]",
"formatEN": "exchange file [sourcePath] to [targetPath]"
},
"/core/xpack/nodes": {
"bodyKeys": [
@@ -5152,4 +5152,4 @@
"formatZH": "从主节点同步设置",
"formatEN": "sync settings from master"
}
}
}
+1
View File
@@ -65,6 +65,7 @@ const (
TaskScopeSystem = "System"
TaskScopeScript = "ScriptLibrary"
TaskScopeNodeFile = "NodeFile"
TaskScopeNodeSSL = "NodeSSL"
TaskScopeAppBackup = "AppBackup"
TaskScopeCluster = "Cluster"
TaskScopeAppInstall = "AppInstallTask"
+6 -6
View File
@@ -1880,15 +1880,15 @@
},
"/core/xpack/exchange/file": {
"bodyKeys": [
"source",
"dest",
"sourceNode",
"targetNode",
"sourcePath",
"destPath"
"targetPath"
],
"paramKeys": [],
"beforeFunctions": [],
"formatZH": "交换文件 [sourcePath] 到 [destPath]",
"formatEN": "exchange file [sourcePath] to [destPath]"
"formatZH": "交换文件 [sourcePath] 到 [targetPath]",
"formatEN": "exchange file [sourcePath] to [targetPath]"
},
"/core/xpack/nodes": {
"bodyKeys": [
@@ -5152,4 +5152,4 @@
"formatZH": "从主节点同步设置",
"formatEN": "sync settings from master"
}
}
}
+2 -2
View File
@@ -183,9 +183,9 @@ var WebUrlMap = map[string]struct{}{
"/xpack/node/dashboard": {},
"/xpack/node": {},
"/xpack/simple-node": {},
"/xpack/sync": {},
"/xpack/sync/file": {},
"/xpack/sync/image": {},
"/xpack/sync/cert": {},
"/xpack/sync/ssl": {},
"/xpack/sync/app": {},
"/xpack/app": {},
"/xpack/app-upgrade": {},
+4 -1
View File
@@ -321,7 +321,10 @@ HandlePublicKey: "Handle node public key"
ExchangeFile: "Start syncing {{ .sourcePath }} from node {{ .source }} to node {{ .dest }}:{{ .destPath }}"
TaskRsync: "Sync"
NodeFile: "Node file"
ImageSyncTaskName: "Image sync {{ .source }} -> {{ .count }} nodes"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "Save image {{ .image }}"
ImageSyncSaveTags: "Save image tags {{ .tags }}"
ImageSyncToNode: "Sync image {{ .image }} to node {{ .node }}"
+4 -1
View File
@@ -315,7 +315,10 @@ HandlePublicKey: "Handle node public key"
ExchangeFile: "Start syncing {{ .sourcePath }} from node {{ .source }} to node {{ .dest }}:{{ .destPath }}"
TaskRsync: "Sync"
NodeFile: "Node file"
ImageSyncTaskName: "Image sync {{ .source }} -> {{ .count }} nodes"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "Save image {{ .image }}"
ImageSyncSaveTags: "Save image tags {{ .tags }}"
ImageSyncToNode: "Sync image {{ .image }} to node {{ .node }}"
+4 -1
View File
@@ -321,7 +321,10 @@ HandlePublicKey: "مدیریت کلید عمومی گره"
ExchangeFile: "شروع همگام‌سازی {{ .sourcePath }} از گره {{ .source }} به گره {{ .dest }}:{{ .destPath }}"
TaskRsync: "همگام‌سازی"
NodeFile: "فایل گره"
ImageSyncTaskName: "همگام‌سازی تصویر {{ .source }} -> {{ .count }} گره"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "ذخیره تصویر {{ .image }}"
ImageSyncSaveTags: "ذخیره برچسب‌های تصویر {{ .tags }}"
ImageSyncToNode: "همگام‌سازی تصویر {{ .image }} به گره {{ .node }}"
+4 -1
View File
@@ -315,7 +315,10 @@ HandlePublicKey: "Handle node public key"
ExchangeFile: "Start syncing {{ .sourcePath }} from node {{ .source }} to node {{ .dest }}:{{ .destPath }}"
TaskRsync: "Sync"
NodeFile: "Node file"
ImageSyncTaskName: "Image sync {{ .source }} -> {{ .count }} nodes"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "Save image {{ .image }}"
ImageSyncSaveTags: "Save image tags {{ .tags }}"
ImageSyncToNode: "Sync image {{ .image }} to node {{ .node }}"
+4 -1
View File
@@ -314,7 +314,10 @@ HandlePublicKey: "Handle node public key"
ExchangeFile: "Start syncing {{ .sourcePath }} from node {{ .source }} to node {{ .dest }}:{{ .destPath }}"
TaskRsync: "Sync"
NodeFile: "Node file"
ImageSyncTaskName: "Image sync {{ .source }} -> {{ .count }} nodes"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "Save image {{ .image }}"
ImageSyncSaveTags: "Save image tags {{ .tags }}"
ImageSyncToNode: "Sync image {{ .image }} to node {{ .node }}"
+4 -1
View File
@@ -309,7 +309,10 @@ HandlePublicKey: "Handle node public key"
ExchangeFile: "Start syncing {{ .sourcePath }} from node {{ .source }} to node {{ .dest }}:{{ .destPath }}"
TaskRsync: "Sync"
NodeFile: "Node file"
ImageSyncTaskName: "Image sync {{ .source }} -> {{ .count }} nodes"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "Save image {{ .image }}"
ImageSyncSaveTags: "Save image tags {{ .tags }}"
ImageSyncToNode: "Sync image {{ .image }} to node {{ .node }}"
+4 -1
View File
@@ -314,7 +314,10 @@ HandlePublicKey: "Handle node public key"
ExchangeFile: "Start syncing {{ .sourcePath }} from node {{ .source }} to node {{ .dest }}:{{ .destPath }}"
TaskRsync: "Sync"
NodeFile: "Node file"
ImageSyncTaskName: "Image sync {{ .source }} -> {{ .count }} nodes"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "Save image {{ .image }}"
ImageSyncSaveTags: "Save image tags {{ .tags }}"
ImageSyncToNode: "Sync image {{ .image }} to node {{ .node }}"
+4 -1
View File
@@ -313,7 +313,10 @@ HandlePublicKey: "Handle node public key"
ExchangeFile: "Start syncing {{ .sourcePath }} from node {{ .source }} to node {{ .dest }}:{{ .destPath }}"
TaskRsync: "Sync"
NodeFile: "Node file"
ImageSyncTaskName: "Image sync {{ .source }} -> {{ .count }} nodes"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "Save image {{ .image }}"
ImageSyncSaveTags: "Save image tags {{ .tags }}"
ImageSyncToNode: "Sync image {{ .image }} to node {{ .node }}"
+4 -1
View File
@@ -313,7 +313,10 @@ HandlePublicKey: "Handle node public key"
ExchangeFile: "Start syncing {{ .sourcePath }} from node {{ .source }} to node {{ .dest }}:{{ .destPath }}"
TaskRsync: "Sync"
NodeFile: "Node file"
ImageSyncTaskName: "Image sync {{ .source }} -> {{ .count }} nodes"
ImageSyncTaskName: "Image sync {{ .count }} images"
SSLSyncTaskName: "Certificate sync {{ .count }} certificates"
AppSyncTaskName: "App sync {{ .name }}"
SSLSyncToNode: "Push certificate [{{ .cert }}] to node [{{ .node }}]"
ImageSyncSave: "Save image {{ .image }}"
ImageSyncSaveTags: "Save image tags {{ .tags }}"
ImageSyncToNode: "Sync image {{ .image }} to node {{ .node }}"
+4 -1
View File
@@ -316,7 +316,10 @@ HandlePublicKey: "處理節點公鑰"
ExchangeFile: "開始從 {{ .source }} 節點同步 {{ .sourcePath }} 到 {{ .dest }} 節點 {{ .destPath }}"
TaskRsync: "同步"
NodeFile: "節點檔案"
ImageSyncTaskName: "映像同步 {{ .source }} -> {{ .count }} 個節點"
ImageSyncTaskName: "映像同步 {{ .count }} 張映像"
SSLSyncTaskName: "憑證同步 {{ .count }} 張憑證"
AppSyncTaskName: "應用同步 {{ .name }}"
SSLSyncToNode: "推送憑證 [{{ .cert }}] 到節點 [{{ .node }}]"
ImageSyncSave: "儲存映像 {{ .image }}"
ImageSyncSaveTags: "儲存映像標籤 {{ .tags }}"
ImageSyncToNode: "同步映像 {{ .image }} 到節點 {{ .node }}"
+4 -1
View File
@@ -322,7 +322,10 @@ HandlePublicKey: "处理节点公钥"
ExchangeFile: "开始从 {{ .source }} 节点同步 {{ .sourcePath }} 到 {{ .dest }} 节点 {{ .destPath }}"
TaskRsync: "同步"
NodeFile: "节点文件"
ImageSyncTaskName: "镜像同步 {{ .source }} -> {{ .count }} 个节点"
ImageSyncTaskName: "镜像同步 {{ .count }} 张镜像"
SSLSyncTaskName: "证书同步 {{ .count }} 张证书"
AppSyncTaskName: "应用同步 {{ .name }}"
SSLSyncToNode: "推送证书 [{{ .cert }}] 到节点 [{{ .node }}]"
ImageSyncSave: "保存镜像 {{ .image }}"
ImageSyncSaveTags: "保存镜像标签 {{ .tags }}"
ImageSyncToNode: "同步镜像 {{ .image }} 到节点 {{ .node }}"
+2 -1
View File
@@ -181,7 +181,7 @@ export namespace App {
message: string;
httpPort: number;
container: string;
env: { [key: string]: string };
env: { [key: string]: any };
appKey: string;
}
@@ -209,6 +209,7 @@ export namespace App {
app: App.AppDetail;
linkDB: boolean;
resourceKeys?: string[];
env?: { [key: string]: any };
}
export interface AppInstalledOption {
+3 -3
View File
@@ -5527,10 +5527,10 @@ const message = {
imageBatchDesc: 'Select a source node and image first, then batch-transfer to multiple target nodes.',
imageBatchConfirmPrefix: 'About to transfer {0} images to {1} nodes, for a total of {2} tasks.',
cert: 'Certificate Sync',
certBatchDesc:
ssl: 'Certificate Sync',
sslBatchDesc:
'After selecting a source node, sync the specified certificate into the current panel environment.',
certBatchConfirmPrefix: 'About to sync {0} certificates to {1} nodes, for a total of {2} tasks.',
sslBatchConfirmPrefix: 'About to sync {0} certificates to {1} nodes, for a total of {2} tasks.',
app: 'Application Transfer',
appBatchDesc:
+3 -3
View File
@@ -5575,10 +5575,10 @@ const message = {
'Seleccione primero el nodo de origen y las imágenes de origen, luego elija los nodos de destino para reenviar.',
imageBatchConfirmPrefix: 'Se enviarán {0} imágenes a {1} nodos, creando {2} tareas.',
cert: 'Sincronización de certificados',
certBatchDesc:
ssl: 'Sincronización de certificados',
sslBatchDesc:
'Después de seleccionar el nodo de origen, los certificados especificados pueden sincronizarse con el entorno actual del panel.',
certBatchConfirmPrefix: 'Se sincronizarán {0} certificados a {1} nodos, creando {2} tareas.',
sslBatchConfirmPrefix: 'Se sincronizarán {0} certificados a {1} nodos, creando {2} tareas.',
app: 'Transferencia de Aplicaciones',
appBatchDesc:
+3 -3
View File
@@ -5499,9 +5499,9 @@ const message = {
'ابتدا یک گره منبع و تصویر را انتخاب کنید، سپس به صورت دسته‌ای به چندین گره هدف انتقال دهید.',
imageBatchConfirmPrefix: 'در حال انتقال {0} تصویر به {1} گره، مجموعاً {2} وظیفه.',
cert: 'همگام‌سازی گواهی',
certBatchDesc: 'پس از انتخاب یک گره منبع، گواهی مشخص شده را به محیط پنل فعلی همگام‌سازی کنید.',
certBatchConfirmPrefix: 'در حال همگام‌سازی {0} گواهی به {1} گره، مجموعاً {2} وظیفه.',
ssl: 'همگام‌سازی گواهی',
sslBatchDesc: 'پس از انتخاب یک گره منبع، گواهی مشخص شده را به محیط پنل فعلی همگام‌سازی کنید.',
sslBatchConfirmPrefix: 'در حال همگام‌سازی {0} گواهی به {1} گره، مجموعاً {2} وظیفه.',
app: 'انتقال برنامه',
appBatchDesc:
+3 -3
View File
@@ -5546,9 +5546,9 @@ const message = {
imageBatchConfirmPrefix:
'{0} 個のイメージを {1} 個のノードへ転送します合計 {2} 件のタスクが作成されます',
cert: '証明書同期',
certBatchDesc: 'ソースノードを選択すると指定した証明書を現在のパネル環境へ同期できます',
certBatchConfirmPrefix: '{0} 件の証明書を {1} 個のノードへ同期します合計 {2} 件のタスクが作成されます',
ssl: '証明書同期',
sslBatchDesc: 'ソースノードを選択すると指定した証明書を現在のパネル環境へ同期できます',
sslBatchConfirmPrefix: '{0} 件の証明書を {1} 個のノードへ同期します合計 {2} 件のタスクが作成されます',
app: 'アプリ転送',
appBatchDesc:
+3 -3
View File
@@ -5431,9 +5431,9 @@ const message = {
imageBatchDesc: '먼저 원본 노드와 원본 이미지를 선택한 대상 노드를 선택하여 전달합니다.',
imageBatchConfirmPrefix: '{0}개의 이미지를 {1} 노드로 전달합니다. {2}개의 작업이 생성됩니다.',
cert: '인증서 동기화',
certBatchDesc: '원본 노드를 선택한 지정된 인증서를 현재 패널 환경으로 동기화할 있습니다.',
certBatchConfirmPrefix: '{0}개의 인증서를 {1} 노드로 동기화합니다. {2}개의 작업이 생성됩니다.',
ssl: '인증서 동기화',
sslBatchDesc: '원본 노드를 선택한 지정된 인증서를 현재 패널 환경으로 동기화할 있습니다.',
sslBatchConfirmPrefix: '{0}개의 인증서를 {1} 노드로 동기화합니다. {2}개의 작업이 생성됩니다.',
app: '애플리케이션 전송',
appBatchDesc:
+3 -3
View File
@@ -5618,10 +5618,10 @@ const message = {
'Pilih nod sumber dan imej sumber terlebih dahulu, kemudian pilih nod sasaran untuk pemindahan.',
imageBatchConfirmPrefix: 'Akan memindahkan {0} imej ke {1} nod, dengan jumlah {2} tugasan.',
cert: 'Penyegerakan Sijil',
certBatchDesc:
ssl: 'Penyegerakan Sijil',
sslBatchDesc:
'Selepas memilih nod sumber, sijil yang ditentukan boleh disegerakkan ke persekitaran panel semasa.',
certBatchConfirmPrefix: 'Akan menyegerakkan {0} sijil ke {1} nod, dengan jumlah {2} tugasan.',
sslBatchConfirmPrefix: 'Akan menyegerakkan {0} sijil ke {1} nod, dengan jumlah {2} tugasan.',
app: 'Pemindahan Aplikasi',
appBatchDesc:
+3 -3
View File
@@ -5767,10 +5767,10 @@ const message = {
'Selecione primeiro o de origem e as imagens de origem e, em seguida, escolha os nós de destino para encaminhamento.',
imageBatchConfirmPrefix: 'Serão encaminhadas {0} imagens para {1} nós, totalizando {2} tarefas.',
cert: 'Sincronização de Certificados',
certBatchDesc:
ssl: 'Sincronização de Certificados',
sslBatchDesc:
'Após selecionar o de origem, os certificados especificados podem ser sincronizados com o ambiente atual do painel.',
certBatchConfirmPrefix: 'Serão sincronizados {0} certificados para {1} nós, totalizando {2} tarefas.',
sslBatchConfirmPrefix: 'Serão sincronizados {0} certificados para {1} nós, totalizando {2} tarefas.',
app: 'Transferência de Aplicativos',
appBatchDesc:
+3 -3
View File
@@ -5619,10 +5619,10 @@ const message = {
'Сначала выберите исходный узел и исходные образы, затем выберите целевые узлы для передачи.',
imageBatchConfirmPrefix: 'Будет передано {0} образов на {1} узлов, всего {2} задач.',
cert: 'Синхронизация сертификатов',
certBatchDesc:
ssl: 'Синхронизация сертификатов',
sslBatchDesc:
'После выбора исходного узла указанные сертификаты можно синхронизировать с текущей средой панели.',
certBatchConfirmPrefix: 'Будет синхронизировано {0} сертификатов на {1} узлов, всего {2} задач.',
sslBatchConfirmPrefix: 'Будет синхронизировано {0} сертификатов на {1} узлов, всего {2} задач.',
app: 'Передача приложений',
appBatchDesc:
+3 -3
View File
@@ -5608,10 +5608,10 @@ const message = {
imageBatchDesc: 'Önce kaynak düğümü ve kaynak imajları seçin, ardından iletim için hedef düğümleri seçin.',
imageBatchConfirmPrefix: '{0} imaj {1} düğüme aktarılacak, toplam {2} görev oluşturulacak.',
cert: 'Sertifika Senkronizasyonu',
certBatchDesc:
ssl: 'Sertifika Senkronizasyonu',
sslBatchDesc:
'Kaynak düğüm seçildikten sonra belirtilen sertifikalar mevcut panel ortamına senkronize edilebilir.',
certBatchConfirmPrefix: '{0} sertifika {1} düğüme senkronize edilecek, toplam {2} görev oluşturulacak.',
sslBatchConfirmPrefix: '{0} sertifika {1} düğüme senkronize edilecek, toplam {2} görev oluşturulacak.',
app: 'Uygulama Aktarımı',
appBatchDesc:
+3 -3
View File
@@ -5151,9 +5151,9 @@ const message = {
imageBatchDesc: '先選擇來源節點和來源映像再批次選擇目標節點進行轉發',
imageBatchConfirmPrefix: '即將把 {0} 張映像轉發到 {1} 個節點 {2} 個任務',
cert: '證書同步',
certBatchDesc: '選擇來源節點後可將指定證書同步到目前面板環境',
certBatchConfirmPrefix: '即將把 {0} 張證書同步到 {1} 個節點 {2} 個任務',
ssl: '證書同步',
sslBatchDesc: '選擇來源節點後可將指定證書同步到目前面板環境',
sslBatchConfirmPrefix: '即將把 {0} 張證書同步到 {1} 個節點 {2} 個任務',
app: '應用對傳',
appBatchDesc: '選擇來源節點單個應用和目標節點後確認資源依賴並執行應用對傳任務',
+3 -3
View File
@@ -5140,9 +5140,9 @@ const message = {
imageBatchDesc: '先选择源节点和源镜像再批量选择目标节点进行转发',
imageBatchConfirmPrefix: '即将把 {0} 张镜像转发到 {1} 个节点 {2} 个任务',
cert: '证书同步',
certBatchDesc: '选择源节点后可将指定证书同步到当前面板环境',
certBatchConfirmPrefix: '即将把 {0} 张证书同步到 {1} 个节点 {2} 个任务',
ssl: '证书同步',
sslBatchDesc: '选择源节点后可将指定证书同步到当前面板环境',
sslBatchConfirmPrefix: '即将把 {0} 张证书同步到 {1} 个节点 {2} 个任务',
app: '应用对传',
appBatchDesc: '选择源节点单个应用和目标节点后确认资源依赖并执行应用对传任务',