mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 06:35:24 +00:00
feat: type the plugin host record, move plugin strings out of core and add lint checks
This commit is contained in:
1 parent
bba06f7ff6
commit
b8bbcd2196
626 files changed
+23884
-4590
No files matched your search
@@ -104,6 +104,17 @@
|
||||
"proxmoxResultFailed": "{{count}} failed",
|
||||
"proxmoxImportComplete": "Proxmox import complete: {{summary}}",
|
||||
"proxmoxDiscoveryFailed": "Discovery failed",
|
||||
"proxmoxImportFailed": "Import failed"
|
||||
"proxmoxImportFailed": "Import failed",
|
||||
"docsLink": "View docs",
|
||||
"hostNotFound": "Host not found",
|
||||
"loadingHost": "Loading host...",
|
||||
"none": "None",
|
||||
"proxmoxGuestsSelected_one": "{{count}} guest — {{selected}} selected",
|
||||
"proxmoxGuestsSelected_other": "{{count}} guests — {{selected}} selected",
|
||||
"proxmoxImportButton_one": "Import {{count}} host",
|
||||
"proxmoxImportButton_other": "Import {{count}} hosts"
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Connected"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimum 15 sekondes. Hoe gereeld om Proxmox-nodusstatistieke te verfris.",
|
||||
"proxmoxStatsNodeOverride": "Nodenaam-oorskrywing",
|
||||
"proxmoxStatsNodeOverrideDesc": "Ignoreer outomatiese opsporing van die Proxmox-nodusnaam (standaard opgespoor via gasheernaam).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Outomaties opgespoor vanaf gasheernaam"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Outomaties opgespoor vanaf gasheernaam",
|
||||
"docsLink": "Bekyk dokumente",
|
||||
"hostNotFound": "Gasheer nie gevind nie",
|
||||
"loadingHost": "Laai gasheer...",
|
||||
"none": "Geen",
|
||||
"proxmoxGuestsSelected_one": "{{count}} gas — {{selected}} gekies",
|
||||
"proxmoxGuestsSelected_other": "{{count}} gaste — {{selected}} gekies",
|
||||
"proxmoxImportButton_one": "Voer {{count}} gasheer in",
|
||||
"proxmoxImportButton_other": "Voer {{count}} gashere in"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox-statistieke",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Geen VM'e of LXC-houers is op hierdie node gevind nie.",
|
||||
"noGuestsMatch": "Geen gaste stem ooreen met die huidige filters nie."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Verbonde"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "الحد الأدنى 15 ثانية. عدد مرات تحديث إحصائيات عقدة Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "تجاوز اسم العقدة",
|
||||
"proxmoxStatsNodeOverrideDesc": "تجاوز الكشف التلقائي عن اسم عقدة Proxmox (يتم الكشف عنه عبر اسم المضيف افتراضيًا).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "تم اكتشافه تلقائيًا من اسم المضيف"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "تم اكتشافه تلقائيًا من اسم المضيف",
|
||||
"docsLink": "عرض المستندات",
|
||||
"hostNotFound": "المضيف غير موجود",
|
||||
"loadingHost": "جارٍ تحميل المضيف...",
|
||||
"none": "لا يوجد",
|
||||
"proxmoxGuestsSelected_one": "{{count}} جهاز ضيف — {{selected}} مُحدد",
|
||||
"proxmoxGuestsSelected_other": "{{count}} أجهزة ضيفة — {{selected}} مُحددة",
|
||||
"proxmoxImportButton_one": "استيراد {{count}} مضيف",
|
||||
"proxmoxImportButton_other": "استيراد {{count}} مضيفين"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "إحصائيات Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "لم يتم العثور على أي أجهزة افتراضية أو حاويات LXC على هذه العقدة.",
|
||||
"noGuestsMatch": "لا يوجد ضيوف يطابقون المعايير الحالية."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "متصل"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Минимум 15 секунди. Колко често да се обновяват статистическите данни за възлите на Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Замяна на името на възела",
|
||||
"proxmoxStatsNodeOverrideDesc": "Игнориране на автоматичното откриване на името на възела Proxmox (по подразбиране се открива чрез името на хоста).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Автоматично разпознато от името на хоста"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Автоматично разпознато от името на хоста",
|
||||
"docsLink": "Преглед на документи",
|
||||
"hostNotFound": "Хостът не е намерен",
|
||||
"loadingHost": "Зареждане на хоста...",
|
||||
"none": "Няма",
|
||||
"proxmoxGuestsSelected_one": "{{count}} гост — {{selected}} избран",
|
||||
"proxmoxGuestsSelected_other": "{{count}} гости — {{selected}} избрани",
|
||||
"proxmoxImportButton_one": "Импортиране на хост {{count}}",
|
||||
"proxmoxImportButton_other": "Импортиране на {{count}} хостове"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Статистика на Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "На този възел не са намерени виртуални машини или LXC контейнери.",
|
||||
"noGuestsMatch": "Няма гости, които да отговарят на текущите филтри."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Свързан"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "সর্বনিম্ন ১৫ সেকেন্ড। কত ঘন ঘন প্রক্সমক্স নোড স্ট্যাটস রিফ্রেশ করতে হবে।",
|
||||
"proxmoxStatsNodeOverride": "নোডের নাম ওভাররাইড",
|
||||
"proxmoxStatsNodeOverrideDesc": "প্রক্সমক্স নোডের নামের স্বয়ংক্রিয় সনাক্তকরণকে অগ্রাহ্য করুন (যা ডিফল্টরূপে হোস্টনেমের মাধ্যমে সনাক্ত করা হয়)।",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "হোস্টনেম থেকে স্বয়ংক্রিয়ভাবে শনাক্ত করা হয়েছে"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "হোস্টনেম থেকে স্বয়ংক্রিয়ভাবে শনাক্ত করা হয়েছে",
|
||||
"docsLink": "নথি দেখুন",
|
||||
"hostNotFound": "হোস্ট খুঁজে পাওয়া যায়নি",
|
||||
"loadingHost": "হোস্ট লোড হচ্ছে...",
|
||||
"none": "কোনোটিই না",
|
||||
"proxmoxGuestsSelected_one": "{{count}} অতিথি — {{selected}} নির্বাচিত",
|
||||
"proxmoxGuestsSelected_other": "{{count}} জন অতিথি — {{selected}} জন নির্বাচিত",
|
||||
"proxmoxImportButton_one": "{{count}} হোস্ট আমদানি করুন",
|
||||
"proxmoxImportButton_other": "{{count}} হোস্ট আমদানি করুন"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "প্রক্সমক্স পরিসংখ্যান",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "এলএক্সসি",
|
||||
"noGuests": "এই নোডে কোনো ভিএম বা এলএক্সসি কন্টেইনার খুঁজে পাওয়া যায়নি।",
|
||||
"noGuestsMatch": "বর্তমান ফিল্টারগুলোর সাথে কোনো অতিথি মেলে না।"
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "সংযুক্ত"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Mínim 15 segons. Amb quina freqüència s'han d'actualitzar les estadístiques del node Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Substitució del nom del node",
|
||||
"proxmoxStatsNodeOverrideDesc": "Anul·la la detecció automàtica del nom del node Proxmox (detectat per defecte mitjançant el nom de l'amfitrió).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detectat automàticament des del nom d'amfitrió"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detectat automàticament des del nom d'amfitrió",
|
||||
"docsLink": "Veure documents",
|
||||
"hostNotFound": "No s'ha trobat l'amfitrió",
|
||||
"loadingHost": "S'està carregant l'amfitrió...",
|
||||
"none": "Cap",
|
||||
"proxmoxGuestsSelected_one": "{{count}} convidat — {{selected}} seleccionat",
|
||||
"proxmoxGuestsSelected_other": "{{count}} convidats — {{selected}} seleccionats",
|
||||
"proxmoxImportButton_one": "Importa l'amfitrió {{count}}",
|
||||
"proxmoxImportButton_other": "Importa els amfitrions {{count}}"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Estadístiques de Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "No s'han trobat màquines virtuals ni contenidors LXC en aquest node.",
|
||||
"noGuestsMatch": "No hi ha convidats que coincideixin amb els filtres actuals."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Connectat"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimálně 15 sekund. Jak často aktualizovat statistiky uzlu Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Přepsání názvu uzlu",
|
||||
"proxmoxStatsNodeOverrideDesc": "Přepsat automatickou detekci názvu uzlu Proxmox (ve výchozím nastavení detekováno pomocí názvu hostitele).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automaticky detekováno z názvu hostitele"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automaticky detekováno z názvu hostitele",
|
||||
"docsLink": "Zobrazit dokumenty",
|
||||
"hostNotFound": "Hostitel nenalezen",
|
||||
"loadingHost": "Načítání hostitele...",
|
||||
"none": "Žádný",
|
||||
"proxmoxGuestsSelected_one": "{{count}} host — {{selected}} vybráno",
|
||||
"proxmoxGuestsSelected_other": "{{count}} hosté — {{selected}} vybráno",
|
||||
"proxmoxImportButton_one": "Importovat hostitele {{count}}",
|
||||
"proxmoxImportButton_other": "Importovat hostitele {{count}}"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Statistiky Proxmoxu",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Na tomto uzlu nebyly nalezeny žádné virtuální počítače ani kontejnery LXC.",
|
||||
"noGuestsMatch": "Aktuálním filtrům neodpovídají žádní hosté."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Připojeno"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimum 15 sekunder. Hvor ofte skal Proxmox-nodestatistikker opdateres.",
|
||||
"proxmoxStatsNodeOverride": "Tilsidesættelse af nodenavn",
|
||||
"proxmoxStatsNodeOverrideDesc": "Tilsidesæt automatisk detektion af Proxmox-nodenavnet (registreres som standard via værtsnavn).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatisk registreret fra værtsnavn"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatisk registreret fra værtsnavn",
|
||||
"docsLink": "Se dokumenter",
|
||||
"hostNotFound": "Værten blev ikke fundet",
|
||||
"loadingHost": "Indlæser vært...",
|
||||
"none": "Ingen",
|
||||
"proxmoxGuestsSelected_one": "{{count}} gæst — {{selected}} valgt",
|
||||
"proxmoxGuestsSelected_other": "{{count}} gæster — {{selected}} valgt",
|
||||
"proxmoxImportButton_one": "Importér {{count}} vært",
|
||||
"proxmoxImportButton_other": "Importér {{count}} værter"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox-statistik",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Der blev ikke fundet nogen VM'er eller LXC-containere på denne node.",
|
||||
"noGuestsMatch": "Ingen gæster matcher de nuværende filtre."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Forbundet"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Mindestens 15 Sekunden. Wie oft sollen die Proxmox-Knotenstatistiken aktualisiert werden?",
|
||||
"proxmoxStatsNodeOverride": "Knotennamen überschreiben",
|
||||
"proxmoxStatsNodeOverrideDesc": "Die automatische Erkennung des Proxmox-Knotennamens (standardmäßig über den Hostnamen ermittelt) kann deaktiviert werden.",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatisch anhand des Hostnamens erkannt"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatisch anhand des Hostnamens erkannt",
|
||||
"docsLink": "Dokumentation anzeigen",
|
||||
"hostNotFound": "Host nicht gefunden",
|
||||
"loadingHost": "Host wird geladen...",
|
||||
"none": "Keine",
|
||||
"proxmoxGuestsSelected_one": "{{count}} Gast — {{selected}} ausgewählt",
|
||||
"proxmoxGuestsSelected_other": "{{count}} Gäste — {{selected}} ausgewählt",
|
||||
"proxmoxImportButton_one": "{{count}} Host importieren",
|
||||
"proxmoxImportButton_other": "{{count}} Hosts importieren"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox-Statistiken",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Auf diesem Knoten wurden keine VMs oder LXC-Container gefunden.",
|
||||
"noGuestsMatch": "Es gibt keine Gäste, die den aktuellen Filtern entsprechen."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Verbunden"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Ελάχιστο 15 δευτερόλεπτα. Πόσο συχνά θα ανανεώνονται τα στατιστικά στοιχεία του κόμβου Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Παράκαμψη ονόματος κόμβου",
|
||||
"proxmoxStatsNodeOverrideDesc": "Παράκαμψη αυτόματης ανίχνευσης του ονόματος κόμβου Proxmox (εντοπίζεται μέσω του ονόματος κεντρικού υπολογιστή από προεπιλογή).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Αυτόματη ανίχνευση από το όνομα κεντρικού υπολογιστή"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Αυτόματη ανίχνευση από το όνομα κεντρικού υπολογιστή",
|
||||
"docsLink": "Προβολή εγγράφων",
|
||||
"hostNotFound": "Δεν βρέθηκε κεντρικός υπολογιστής",
|
||||
"loadingHost": "Φόρτωση κεντρικού υπολογιστή...",
|
||||
"none": "Κανένας",
|
||||
"proxmoxGuestsSelected_one": "{{count}} επισκέπτης — {{selected}} επιλεγμένος",
|
||||
"proxmoxGuestsSelected_other": "{{count}} επισκέπτες — {{selected}} επιλεγμένοι",
|
||||
"proxmoxImportButton_one": "Εισαγωγή κεντρικού υπολογιστή {{count}}",
|
||||
"proxmoxImportButton_other": "Εισαγωγή {{count}} κεντρικών υπολογιστών"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Στατιστικά Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Δεν βρέθηκαν εικονικές μηχανές ή κοντέινερ LXC σε αυτόν τον κόμβο.",
|
||||
"noGuestsMatch": "Δεν υπάρχουν επισκέπτες που να αντιστοιχούν στα τρέχοντα φίλτρα."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Συνδεδεμένος"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Mínimo 15 segundos. Con qué frecuencia se actualizan las estadísticas del nodo Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Anulación del nombre del nodo",
|
||||
"proxmoxStatsNodeOverrideDesc": "Anular la detección automática del nombre del nodo Proxmox (detectado por defecto mediante el nombre de host).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detectado automáticamente a partir del nombre de host."
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detectado automáticamente a partir del nombre de host.",
|
||||
"docsLink": "Ver documentación",
|
||||
"hostNotFound": "Host no encontrado",
|
||||
"loadingHost": "Cargando host...",
|
||||
"none": "Ninguno",
|
||||
"proxmoxGuestsSelected_one": "{{count}} invitado — {{selected}} seleccionado",
|
||||
"proxmoxGuestsSelected_other": "{{count}} invitados — {{selected}} seleccionados",
|
||||
"proxmoxImportButton_one": "Importar {{count}} host",
|
||||
"proxmoxImportButton_other": "Importar {{count}} hosts"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Estadísticas de Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "No se encontraron máquinas virtuales ni contenedores LXC en este nodo.",
|
||||
"noGuestsMatch": "No hay huéspedes que coincidan con los filtros actuales."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Conectado"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Vähintään 15 sekuntia. Kuinka usein Proxmox-solmun tilastot päivitetään.",
|
||||
"proxmoxStatsNodeOverride": "Solmun nimen ohitus",
|
||||
"proxmoxStatsNodeOverrideDesc": "Ohita Proxmox-solmun nimen automaattinen tunnistus (tunnistetaan oletusarvoisesti isäntänimen kautta).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automaattisesti tunnistettu isäntänimestä"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automaattisesti tunnistettu isäntänimestä",
|
||||
"docsLink": "Näytä dokumentit",
|
||||
"hostNotFound": "Isäntää ei löydy",
|
||||
"loadingHost": "Ladataan isäntää...",
|
||||
"none": "Ei mitään",
|
||||
"proxmoxGuestsSelected_one": "{{count}} vieras — {{selected}} valittu",
|
||||
"proxmoxGuestsSelected_other": "{{count}} vieraat — {{selected}} valittu",
|
||||
"proxmoxImportButton_one": "Tuo {{count}} isäntä",
|
||||
"proxmoxImportButton_other": "Tuo {{count}} isäntiä"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox-tilastot",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Tältä solmulta ei löytynyt virtuaalikoneita tai LXC-säilöjä.",
|
||||
"noGuestsMatch": "Yksikään vieras ei vastaa nykyisiä suodattimia."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Yhdistetty"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimum 15 secondes. Fréquence d'actualisation des statistiques du nœud Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Remplacement du nom du nœud",
|
||||
"proxmoxStatsNodeOverrideDesc": "Désactiver la détection automatique du nom du nœud Proxmox (détecté par défaut via le nom d'hôte).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Détection automatique à partir du nom d'hôte"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Détection automatique à partir du nom d'hôte",
|
||||
"docsLink": "Voir la documentation",
|
||||
"hostNotFound": "Hôte introuvable",
|
||||
"loadingHost": "Chargement de l'hôte...",
|
||||
"none": "Aucun",
|
||||
"proxmoxGuestsSelected_one": "{{count}} invité — {{selected}} sélectionné",
|
||||
"proxmoxGuestsSelected_other": "{{count}} invités — {{selected}} sélectionnés",
|
||||
"proxmoxImportButton_one": "Importer {{count}} hôte",
|
||||
"proxmoxImportButton_other": "Importer {{count}} hôtes"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Statistiques Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Aucune machine virtuelle ni conteneur LXC n'a été trouvé sur ce nœud.",
|
||||
"noGuestsMatch": "Aucun invité ne correspond aux filtres actuels."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Connecté"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "מינימום 15 שניות. באיזו תדירות לרענן את סטטיסטיקות הצומת של Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "עקיפת שם הצומת",
|
||||
"proxmoxStatsNodeOverrideDesc": "עקיפת זיהוי אוטומטי של שם הצומת Proxmox (מזוהה דרך שם המארח כברירת מחדל).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "זוהה אוטומטית משם המארח"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "זוהה אוטומטית משם המארח",
|
||||
"docsLink": "הצג מסמכים",
|
||||
"hostNotFound": "המארח לא נמצא",
|
||||
"loadingHost": "טוען מארח...",
|
||||
"none": "אַף לֹא אֶחָד",
|
||||
"proxmoxGuestsSelected_one": "{{count}} אורח — {{selected}} נבחר",
|
||||
"proxmoxGuestsSelected_other": "{{count}} אורחים — {{selected}} נבחרו",
|
||||
"proxmoxImportButton_one": "ייבוא מארח {{count}}",
|
||||
"proxmoxImportButton_other": "ייבוא מארחים {{count}}"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "סטטיסטיקות פרוקסמוקס",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "לא נמצאו מכונות וירטואליות או מכולות LXC בצומת זה.",
|
||||
"noGuestsMatch": "אין אורחים התואמים את המסננים הנוכחיים."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "מְחוּבָּר"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "कम से कम 15 सेकंड। प्रोक्समॉक्स नोड के आंकड़ों को कितनी बार रीफ्रेश करना है?",
|
||||
"proxmoxStatsNodeOverride": "नोड नाम ओवरराइड",
|
||||
"proxmoxStatsNodeOverrideDesc": "Proxmox नोड नाम की स्वतः पहचान को ओवरराइड करें (जो डिफ़ॉल्ट रूप से होस्टनाम के माध्यम से पता लगाया जाता है)।",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "होस्टनाम से स्वतः पता लगाया गया"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "होस्टनाम से स्वतः पता लगाया गया",
|
||||
"docsLink": "दस्तावेज़ देखें",
|
||||
"hostNotFound": "होस्ट नहीं मिला",
|
||||
"loadingHost": "होस्ट लोड हो रहा है...",
|
||||
"none": "कोई नहीं",
|
||||
"proxmoxGuestsSelected_one": "{{count}} अतिथि — {{selected}} चयनित",
|
||||
"proxmoxGuestsSelected_other": "{{count}} अतिथि — {{selected}} चयनित",
|
||||
"proxmoxImportButton_one": "{{count}} होस्ट आयात करें",
|
||||
"proxmoxImportButton_other": "{{count}} होस्ट आयात करें"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "प्रॉक्समॉक्स आँकड़े",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "एलएक्ससी",
|
||||
"noGuests": "इस नोड पर कोई वीएम या एलएक्ससी कंटेनर नहीं मिला।",
|
||||
"noGuestsMatch": "वर्तमान फ़िल्टरों से कोई अतिथि मेल नहीं खाता।"
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "कनेक्टेड"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimum 15 másodperc. A Proxmox csomópont statisztikáinak frissítési gyakorisága.",
|
||||
"proxmoxStatsNodeOverride": "Csomópont nevének felülbírálása",
|
||||
"proxmoxStatsNodeOverrideDesc": "A Proxmox csomópont nevének automatikus észlelésének felülbírálása (alapértelmezés szerint a gazdagépnév alapján észlelhető).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatikusan felismerve a gazdagépnév alapján"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatikusan felismerve a gazdagépnév alapján",
|
||||
"docsLink": "Dokumentumok megtekintése",
|
||||
"hostNotFound": "Nem található gazdagép",
|
||||
"loadingHost": "Gazdagép betöltése...",
|
||||
"none": "Egyik sem",
|
||||
"proxmoxGuestsSelected_one": "{{count}} vendég — {{selected}} kiválasztva",
|
||||
"proxmoxGuestsSelected_other": "{{count}} vendégek — {{selected}} kiválasztva",
|
||||
"proxmoxImportButton_one": "Importálja a {{count}} gazdagépet",
|
||||
"proxmoxImportButton_other": "{{count}} hosztok importálása"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox statisztikák",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Nem találhatók virtuális gépek vagy LXC konténerek ezen a csomóponton.",
|
||||
"noGuestsMatch": "Egyik vendég sem felel meg a jelenlegi szűrőknek."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Csatlakoztatva"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimal 15 detik. Seberapa sering statistik node Proxmox diperbarui.",
|
||||
"proxmoxStatsNodeOverride": "Penggantian nama node",
|
||||
"proxmoxStatsNodeOverrideDesc": "Ganti deteksi otomatis nama node Proxmox (yang secara default dideteksi melalui nama host).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Terdeteksi secara otomatis dari nama host"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Terdeteksi secara otomatis dari nama host",
|
||||
"docsLink": "Lihat dokumen",
|
||||
"hostNotFound": "Host tidak ditemukan",
|
||||
"loadingHost": "Memuat host...",
|
||||
"none": "Tidak ada",
|
||||
"proxmoxGuestsSelected_one": "{{count}} tamu — {{selected}} terpilih",
|
||||
"proxmoxGuestsSelected_other": "{{count}} tamu — {{selected}} terpilih",
|
||||
"proxmoxImportButton_one": "Impor {{count}} host",
|
||||
"proxmoxImportButton_other": "Impor {{count}} host"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Statistik Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Tidak ditemukan VM atau kontainer LXC pada node ini.",
|
||||
"noGuestsMatch": "Tidak ada tamu yang sesuai dengan filter saat ini."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Terhubung"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimo 15 secondi. Frequenza di aggiornamento delle statistiche dei nodi Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Sovrascrittura del nome del nodo",
|
||||
"proxmoxStatsNodeOverrideDesc": "Ignora il rilevamento automatico del nome del nodo Proxmox (rilevato tramite nome host per impostazione predefinita).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Rilevato automaticamente dal nome host"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Rilevato automaticamente dal nome host",
|
||||
"docsLink": "Visualizza documentazione",
|
||||
"hostNotFound": "Host non trovato",
|
||||
"loadingHost": "Caricamento host...",
|
||||
"none": "Nessuna",
|
||||
"proxmoxGuestsSelected_one": "{{count}} guest — {{selected}} selezionato",
|
||||
"proxmoxGuestsSelected_other": "{{count}} guest — {{selected}} selezionati",
|
||||
"proxmoxImportButton_one": "Importa {{count}} host",
|
||||
"proxmoxImportButton_other": "Importa {{count}} host"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Statistiche di Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Nessuna macchina virtuale o container LXC trovato su questo nodo.",
|
||||
"noGuestsMatch": "Nessun ospite corrisponde ai filtri attualmente attivi."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Connesso"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "最低15秒。Proxmoxノードの統計情報を更新する頻度。",
|
||||
"proxmoxStatsNodeOverride": "ノード名の上書き",
|
||||
"proxmoxStatsNodeOverrideDesc": "Proxmoxノード名の自動検出(デフォルトではホスト名で検出)を上書きします。",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "ホスト名から自動検出"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "ホスト名から自動検出",
|
||||
"docsLink": "ドキュメントを表示",
|
||||
"hostNotFound": "ホストが見つかりません",
|
||||
"loadingHost": "ホストを読み込み中...",
|
||||
"none": "なし",
|
||||
"proxmoxGuestsSelected_one": "{{count}} ゲスト — {{selected}} 選択中",
|
||||
"proxmoxGuestsSelected_other": "{{count}} ゲスト — {{selected}} 選択中",
|
||||
"proxmoxImportButton_one": "{{count}} ホストをインポート",
|
||||
"proxmoxImportButton_other": "{{count}} 台のホストをインポート"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox統計情報",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "このノード上にはVMまたはLXCコンテナは見つかりませんでした。",
|
||||
"noGuestsMatch": "現在の検索条件に一致するゲストはいません。"
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "接続中"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "최소 15초. Proxmox 노드 통계를 새로 고치는 빈도.",
|
||||
"proxmoxStatsNodeOverride": "노드 이름 재정의",
|
||||
"proxmoxStatsNodeOverrideDesc": "Proxmox 노드 이름 자동 감지 기능을 재정의합니다(기본적으로 호스트 이름을 통해 감지됨).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "호스트 이름에서 자동 감지됨"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "호스트 이름에서 자동 감지됨",
|
||||
"docsLink": "문서 보기",
|
||||
"hostNotFound": "호스트를 찾을 수 없습니다",
|
||||
"loadingHost": "호스트 로드 중...",
|
||||
"none": "없음",
|
||||
"proxmoxGuestsSelected_one": "게스트 {{count}}개 — {{selected}}개 선택됨",
|
||||
"proxmoxGuestsSelected_other": "게스트 {{count}}개 — {{selected}}개 선택됨",
|
||||
"proxmoxImportButton_one": "호스트 {{count}}개 가져오기",
|
||||
"proxmoxImportButton_other": "{{count}}개 호스트 가져오기"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "프록스목스 통계",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "이 노드에서 VM 또는 LXC 컨테이너를 찾을 수 없습니다.",
|
||||
"noGuestsMatch": "현재 필터 조건에 맞는 투숙객이 없습니다."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "연결됨"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimaal 15 seconden. Hoe vaak moeten de Proxmox-node-statistieken worden vernieuwd?",
|
||||
"proxmoxStatsNodeOverride": "Knooppuntnaam overschrijven",
|
||||
"proxmoxStatsNodeOverrideDesc": "Schakel de automatische detectie van de Proxmox-knooppuntnaam uit (deze wordt standaard gedetecteerd via de hostnaam).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatisch gedetecteerd op basis van hostnaam"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatisch gedetecteerd op basis van hostnaam",
|
||||
"docsLink": "Documenten bekijken",
|
||||
"hostNotFound": "Host niet gevonden",
|
||||
"loadingHost": "Host wordt geladen...",
|
||||
"none": "Geen",
|
||||
"proxmoxGuestsSelected_one": "{{count}} gast — {{selected}} geselecteerd",
|
||||
"proxmoxGuestsSelected_other": "{{count}} gasten — {{selected}} geselecteerd",
|
||||
"proxmoxImportButton_one": "Importeer {{count}} host",
|
||||
"proxmoxImportButton_other": "Importeer {{count}} hosts"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox-statistieken",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Er zijn geen VM's of LXC-containers gevonden op dit knooppunt.",
|
||||
"noGuestsMatch": "Er zijn geen gasten die aan de huidige filters voldoen."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Aangesloten"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimum 15 sekunder. Hvor ofte Proxmox-nodestatistikken skal oppdateres.",
|
||||
"proxmoxStatsNodeOverride": "Overstyring av nodenavn",
|
||||
"proxmoxStatsNodeOverrideDesc": "Overstyr automatisk deteksjon av Proxmox-nodenavnet (detekteres via vertsnavn som standard).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatisk oppdaget fra vertsnavn"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatisk oppdaget fra vertsnavn",
|
||||
"docsLink": "Vis dokumenter",
|
||||
"hostNotFound": "Verten ble ikke funnet",
|
||||
"loadingHost": "Laster inn vert ...",
|
||||
"none": "Ingen",
|
||||
"proxmoxGuestsSelected_one": "{{count}} gjest — {{selected}} valgt",
|
||||
"proxmoxGuestsSelected_other": "{{count}} gjester — {{selected}} valgt",
|
||||
"proxmoxImportButton_one": "Importer {{count}} vert",
|
||||
"proxmoxImportButton_other": "Importer {{count}} verter"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox-statistikk",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Ingen virtuelle maskiner eller LXC-containere funnet på denne noden.",
|
||||
"noGuestsMatch": "Ingen gjester samsvarer med de gjeldende filtrene."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Tilkoblet"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minimum 15 sekund. Jak często odświeżać statystyki węzła Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Nadpisanie nazwy węzła",
|
||||
"proxmoxStatsNodeOverrideDesc": "Zastąp automatyczne wykrywanie nazwy węzła Proxmox (domyślnie wykrywane za pomocą nazwy hosta).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatycznie wykryto na podstawie nazwy hosta"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatycznie wykryto na podstawie nazwy hosta",
|
||||
"docsLink": "Zobacz dokumentację",
|
||||
"hostNotFound": "Nie znaleziono hosta",
|
||||
"loadingHost": "Ładowanie hosta...",
|
||||
"none": "Brak",
|
||||
"proxmoxGuestsSelected_one": "{{count}} gość, wybrano {{selected}}",
|
||||
"proxmoxGuestsSelected_other": "{{count}} gości, wybrano {{selected}}",
|
||||
"proxmoxImportButton_one": "Importuj {{count}} host",
|
||||
"proxmoxImportButton_other": "Importuj {{count}} hostów"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Statystyki Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Nie znaleziono maszyn wirtualnych ani kontenerów LXC na tym węźle.",
|
||||
"noGuestsMatch": "Żaden gość nie pasuje do bieżących filtrów."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Połączono"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Mínimo de 15 segundos. Com que frequência as estatísticas do nó Proxmox devem ser atualizadas.",
|
||||
"proxmoxStatsNodeOverride": "Substituição do nome do nó",
|
||||
"proxmoxStatsNodeOverrideDesc": "Substituir a detecção automática do nome do nó Proxmox (detectado por padrão através do nome do host).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detectado automaticamente a partir do nome do host"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detectado automaticamente a partir do nome do host",
|
||||
"docsLink": "Ver documentos",
|
||||
"hostNotFound": "Host não encontrado",
|
||||
"loadingHost": "Carregando host...",
|
||||
"none": "Nenhum",
|
||||
"proxmoxGuestsSelected_one": "{{count}} convidado — {{selected}} selecionado",
|
||||
"proxmoxGuestsSelected_other": "{{count}} convidados — {{selected}} selecionados",
|
||||
"proxmoxImportButton_one": "Importar {{count}} host",
|
||||
"proxmoxImportButton_other": "Importar {{count}} hosts"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Estatísticas do Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Nenhuma máquina virtual ou contêiner LXC foi encontrado neste nó.",
|
||||
"noGuestsMatch": "Nenhum hóspede corresponde aos filtros atuais."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Conectado"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Mínimo de 15 segundos. Com que frequência as estatísticas do nó Proxmox devem ser atualizadas.",
|
||||
"proxmoxStatsNodeOverride": "Substituição do nome do nó",
|
||||
"proxmoxStatsNodeOverrideDesc": "Substituir a deteção automática do nome do nó Proxmox (detetado por defeito através do nome do host).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detetado automaticamente a partir do nome do host"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detetado automaticamente a partir do nome do host",
|
||||
"docsLink": "Ver documentação",
|
||||
"hostNotFound": "Host não encontrado",
|
||||
"loadingHost": "A carregar o host...",
|
||||
"none": "Nenhum",
|
||||
"proxmoxGuestsSelected_one": "{{count}} convidado — {{selected}} selecionado",
|
||||
"proxmoxGuestsSelected_other": "{{count}} convidados — {{selected}} selecionados",
|
||||
"proxmoxImportButton_one": "Importar {{count}} host",
|
||||
"proxmoxImportButton_other": "Importar {{count}} hosts"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Estatísticas do Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Nenhuma máquina virtual ou contentor LXC foi encontrado neste nó.",
|
||||
"noGuestsMatch": "Nenhum hóspede corresponde aos filtros atuais."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Ligado"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minim 15 secunde. Cât de des se actualizează statisticile nodului Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Suprascriere nume nod",
|
||||
"proxmoxStatsNodeOverrideDesc": "Suprascrie detectarea automată a numelui nodului Proxmox (detectat implicit prin numele de gazdă).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detectat automat de la numele de gazdă"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Detectat automat de la numele de gazdă",
|
||||
"docsLink": "Vizualizați documentele",
|
||||
"hostNotFound": "Gazdă negăsită",
|
||||
"loadingHost": "Se încarcă gazda...",
|
||||
"none": "Nici unul",
|
||||
"proxmoxGuestsSelected_one": "{{count}} invitat — {{selected}} selectat",
|
||||
"proxmoxGuestsSelected_other": "{{count}} invitați — {{selected}} selectați",
|
||||
"proxmoxImportButton_one": "Importați gazda {{count}}",
|
||||
"proxmoxImportButton_other": "Importați gazde {{count}}"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Statistici Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Nu s-au găsit mașini virtuale sau containere LXC pe acest nod.",
|
||||
"noGuestsMatch": "Niciun invitat nu corespunde filtrelor actuale."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Conectat"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Минимум 15 секунд. Как часто обновлять статистику узлов Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Переопределение имени узла",
|
||||
"proxmoxStatsNodeOverrideDesc": "Отключить автоматическое определение имени узла Proxmox (по умолчанию определяется по имени хоста).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Автоматически определено по имени хоста"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Автоматически определено по имени хоста",
|
||||
"docsLink": "Документация",
|
||||
"hostNotFound": "Хост не найден",
|
||||
"loadingHost": "Загрузка хоста...",
|
||||
"none": "Нет",
|
||||
"proxmoxGuestsSelected_one": "{{count}} гость — {{selected}} выбрано",
|
||||
"proxmoxGuestsSelected_other": "{{count}} гостей — {{selected}} выбрано",
|
||||
"proxmoxImportButton_one": "Импортировать {{count}} хост",
|
||||
"proxmoxImportButton_other": "Импортировать {{count}} хостов"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Статистика Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "ЛХС",
|
||||
"noGuests": "На этом узле не обнаружено виртуальных машин или контейнеров LXC.",
|
||||
"noGuestsMatch": "Ни один из гостей не соответствует текущим фильтрам."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Подключено"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Минимум 15 секунди. Колико често освежавати статистику Proxmox чвора.",
|
||||
"proxmoxStatsNodeOverride": "Замена имена чвора",
|
||||
"proxmoxStatsNodeOverrideDesc": "Поништи аутоматско откривање имена Proxmox чвора (подразумевано се открива преко имена хоста).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Аутоматски детектовано на основу имена хоста"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Аутоматски детектовано на основу имена хоста",
|
||||
"docsLink": "Прикажи документе",
|
||||
"hostNotFound": "Хост није пронађен",
|
||||
"loadingHost": "Учитавање хоста...",
|
||||
"none": "Ниједан",
|
||||
"proxmoxGuestsSelected_one": "{{count}} гост — {{selected}} изабрано",
|
||||
"proxmoxGuestsSelected_other": "{{count}} гости — {{selected}} изабрано",
|
||||
"proxmoxImportButton_one": "Увоз {{count}} хоста",
|
||||
"proxmoxImportButton_other": "Увези {{count}} хостова"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox статистика",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "На овом чвору нису пронађене виртуелне машине или LXC контејнери.",
|
||||
"noGuestsMatch": "Ниједан гост не одговара тренутним филтерима."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Повезано"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Minst 15 sekunder. Hur ofta Proxmox-nodstatistik ska uppdateras.",
|
||||
"proxmoxStatsNodeOverride": "Åsidosättning av nodnamn",
|
||||
"proxmoxStatsNodeOverrideDesc": "Åsidosätt automatisk detektering av Proxmox-nodnamnet (detekteras via värdnamn som standard).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatiskt identifierad från värdnamn"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Automatiskt identifierad från värdnamn",
|
||||
"docsLink": "Visa dokument",
|
||||
"hostNotFound": "Värden hittades inte",
|
||||
"loadingHost": "Laddar värd...",
|
||||
"none": "Ingen",
|
||||
"proxmoxGuestsSelected_one": "{{count}} gäst — {{selected}} vald",
|
||||
"proxmoxGuestsSelected_other": "{{count}} gäster — {{selected}} vald",
|
||||
"proxmoxImportButton_one": "Importera {{count}} värd",
|
||||
"proxmoxImportButton_other": "Importera {{count}} värdar"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox-statistik",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Inga virtuella maskiner eller LXC-behållare hittades på den här noden.",
|
||||
"noGuestsMatch": "Inga gäster matchar de aktuella filtren."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Ansluten"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "อย่างน้อย 15 วินาที ความถี่ในการอัปเดตสถิติโหนด Proxmox",
|
||||
"proxmoxStatsNodeOverride": "การแทนที่ชื่อโหนด",
|
||||
"proxmoxStatsNodeOverrideDesc": "ยกเลิกการตรวจจับชื่อโหนด Proxmox อัตโนมัติ (โดยค่าเริ่มต้นจะตรวจจับผ่านชื่อโฮสต์)",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "ตรวจจับอัตโนมัติจากชื่อโฮสต์"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "ตรวจจับอัตโนมัติจากชื่อโฮสต์",
|
||||
"docsLink": "ดูเอกสาร",
|
||||
"hostNotFound": "ไม่พบโฮสต์",
|
||||
"loadingHost": "กำลังโหลดโฮสต์...",
|
||||
"none": "ไม่มี",
|
||||
"proxmoxGuestsSelected_one": "{{count}} แขก — {{selected}} เลือกแล้ว",
|
||||
"proxmoxGuestsSelected_other": "แขก {{count}} คน — แขก {{selected}} คน ที่เลือก",
|
||||
"proxmoxImportButton_one": "นำเข้าโฮสต์ {{count}}",
|
||||
"proxmoxImportButton_other": "นำเข้าโฮสต์ {{count}}"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "สถิติ Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "ไม่พบเครื่องเสมือน (VM) หรือคอนเทนเนอร์ LXC บนโหนดนี้",
|
||||
"noGuestsMatch": "ไม่มีแขกท่านใดตรงกับตัวกรองที่มีอยู่ในขณะนี้"
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "เชื่อมต่อแล้ว"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "En az 15 saniye. Proxmox düğüm istatistiklerinin ne sıklıkla yenilenmesi gerektiği.",
|
||||
"proxmoxStatsNodeOverride": "Düğüm adı geçersiz kılma",
|
||||
"proxmoxStatsNodeOverrideDesc": "Proxmox düğüm adının otomatik olarak algılanmasını (varsayılan olarak ana bilgisayar adı üzerinden algılanır) geçersiz kılın.",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Ana bilgisayar adından otomatik olarak algılandı"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Ana bilgisayar adından otomatik olarak algılandı",
|
||||
"docsLink": "Dokümanları görüntüle",
|
||||
"hostNotFound": "Host bulunamadı",
|
||||
"loadingHost": "Host yükleniyor...",
|
||||
"none": "Hiçbiri",
|
||||
"proxmoxGuestsSelected_one": "{{count}} misafir — {{selected}} seçili",
|
||||
"proxmoxGuestsSelected_other": "{{count}} misafir — {{selected}} seçili",
|
||||
"proxmoxImportButton_one": "{{count}} ana makineyi içe aktar",
|
||||
"proxmoxImportButton_other": "{{count}} sunucuyu içe aktar"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox İstatistikleri",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Bu düğümde hiçbir sanal makine veya LXC kapsayıcısı bulunamadı.",
|
||||
"noGuestsMatch": "Mevcut filtrelere uyan konuk bulunamadı."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Bağlandı"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Мінімум 15 секунд. Як часто оновлювати статистику вузла Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Перевизначення назви вузла",
|
||||
"proxmoxStatsNodeOverrideDesc": "Перевизначити автоматичне визначення імені вузла Proxmox (за замовчуванням визначається через ім'я хоста).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Автоматично визначено за назвою хоста"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Автоматично визначено за назвою хоста",
|
||||
"docsLink": "Переглянути документи",
|
||||
"hostNotFound": "Хост не знайдено",
|
||||
"loadingHost": "Завантаження хоста...",
|
||||
"none": "Жоден",
|
||||
"proxmoxGuestsSelected_one": "{{count}} гість — {{selected}} вибрано",
|
||||
"proxmoxGuestsSelected_other": "{{count}} гостей — {{selected}} вибрано",
|
||||
"proxmoxImportButton_one": "Імпортувати хост {{count}}",
|
||||
"proxmoxImportButton_other": "Імпортувати {{count}} хостів"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Статистика Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "На цьому вузлі не знайдено віртуальних машин або контейнерів LXC.",
|
||||
"noGuestsMatch": "Немає гостей, які відповідають поточним фільтрам."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Підключено"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "Tối thiểu 15 giây. Tần suất làm mới số liệu thống kê của node Proxmox.",
|
||||
"proxmoxStatsNodeOverride": "Ghi đè tên nút",
|
||||
"proxmoxStatsNodeOverrideDesc": "Ghi đè tính năng tự động phát hiện tên nút Proxmox (mặc định được phát hiện thông qua tên máy chủ).",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Tự động nhận diện từ tên máy chủ"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "Tự động nhận diện từ tên máy chủ",
|
||||
"docsLink": "Xem tài liệu",
|
||||
"hostNotFound": "Không tìm thấy máy chủ",
|
||||
"loadingHost": "Đang tải máy chủ...",
|
||||
"none": "Không có",
|
||||
"proxmoxGuestsSelected_one": "{{count}} máy khách — đã chọn {{selected}}",
|
||||
"proxmoxGuestsSelected_other": "{{count}} máy khách — đã chọn {{selected}}",
|
||||
"proxmoxImportButton_one": "Nhập {{count}} máy chủ",
|
||||
"proxmoxImportButton_other": "Nhập {{count}} máy chủ"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Thống kê Proxmox",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "Không tìm thấy máy ảo hoặc vùng chứa LXC nào trên nút này.",
|
||||
"noGuestsMatch": "Hiện không có khách nào phù hợp với bộ lọc hiện tại."
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "Đã kết nối"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "最短间隔 15 秒。Proxmox 节点统计信息刷新频率。",
|
||||
"proxmoxStatsNodeOverride": "覆盖节点名称",
|
||||
"proxmoxStatsNodeOverrideDesc": "覆盖自动检测的 Proxmox 节点名称(默认情况下通过主机名检测)。",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "从主机名自动检测"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "从主机名自动检测",
|
||||
"docsLink": "查看文档",
|
||||
"hostNotFound": "未找到主机",
|
||||
"loadingHost": "正在加载主机...",
|
||||
"none": "无",
|
||||
"proxmoxGuestsSelected_one": "{{count}} 个客户主机 — 已选择 {{selected}} 个",
|
||||
"proxmoxGuestsSelected_other": "{{count}} 个客户主机 — 已选择 {{selected}} 个",
|
||||
"proxmoxImportButton_one": "导入 {{count}} 个主机",
|
||||
"proxmoxImportButton_other": "导入 {{count}} 个主机"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox 统计数据",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "此节点上未找到虚拟机或 LXC 容器。",
|
||||
"noGuestsMatch": "没有符合当前筛选条件的客户主机。"
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "已连接"
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,15 @@
|
||||
"proxmoxStatsPollIntervalDesc": "最短間隔 15 秒。 Proxmox 節點統計資訊刷新頻率。",
|
||||
"proxmoxStatsNodeOverride": "節點名稱覆蓋",
|
||||
"proxmoxStatsNodeOverrideDesc": "覆蓋 Proxmox 節點名稱的自動偵測(預設透過主機名稱偵測)。",
|
||||
"proxmoxStatsNodeOverridePlaceholder": "從主機名稱自動偵測"
|
||||
"proxmoxStatsNodeOverridePlaceholder": "從主機名稱自動偵測",
|
||||
"docsLink": "檢視文件",
|
||||
"hostNotFound": "找不到主機",
|
||||
"loadingHost": "正在載入主機...",
|
||||
"none": "無",
|
||||
"proxmoxGuestsSelected_one": "{{count}} 個訪客主機 — 已選取 {{selected}}",
|
||||
"proxmoxGuestsSelected_other": "{{count}} 個訪客主機 — 已選取 {{selected}}",
|
||||
"proxmoxImportButton_one": "匯入 {{count}} 台主機",
|
||||
"proxmoxImportButton_other": "匯入 {{count}} 台主機"
|
||||
},
|
||||
"proxmoxStats": {
|
||||
"tabTitle": "Proxmox 統計數據",
|
||||
@@ -102,5 +110,8 @@
|
||||
"filterLxc": "LXC",
|
||||
"noGuests": "此節點上未發現虛擬機器或 LXC 容器。",
|
||||
"noGuestsMatch": "沒有符合目前篩選條件的客人。"
|
||||
},
|
||||
"terminal": {
|
||||
"connected": "已連線"
|
||||
}
|
||||
}
|
||||
@@ -49,8 +49,8 @@ export function proxmoxSourceKey(source: {
|
||||
return `${source.sourceHostId}:${source.node}:${source.type}:${source.vmid}`;
|
||||
}
|
||||
|
||||
export interface ImportedGuest {
|
||||
host: Record<string, unknown>;
|
||||
export interface ImportedGuest<H = Record<string, unknown>> {
|
||||
host: H;
|
||||
config: Record<string, unknown>;
|
||||
source: ProxmoxSource;
|
||||
}
|
||||
@@ -60,13 +60,13 @@ export interface ImportedGuest {
|
||||
* source lives in each guest's proxmoxConfig host setting, not on the host
|
||||
* row, so the caller passes both.
|
||||
*/
|
||||
export function indexImportedGuests(
|
||||
hosts: Record<string, unknown>[],
|
||||
export function indexImportedGuests<H extends { id: unknown }>(
|
||||
hosts: H[],
|
||||
configs: Array<{ hostId: number; value: unknown }>,
|
||||
sourceHostId: number,
|
||||
): Map<string, ImportedGuest> {
|
||||
): Map<string, ImportedGuest<H>> {
|
||||
const configById = new Map(configs.map((c) => [c.hostId, c.value]));
|
||||
const out = new Map<string, ImportedGuest>();
|
||||
const out = new Map<string, ImportedGuest<H>>();
|
||||
for (const host of hosts) {
|
||||
const config = parseJsonObject(configById.get(Number(host.id)));
|
||||
const source = getProxmoxSource(config);
|
||||
|
||||
@@ -10,8 +10,3 @@ export function parseProxmoxJumpHosts(raw: unknown): unknown[] | null {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function serializeProxmoxJumpHosts(raw: unknown): string | null {
|
||||
const parsed = parseProxmoxJumpHosts(raw);
|
||||
return parsed ? JSON.stringify(parsed) : null;
|
||||
}
|
||||
@@ -3,16 +3,14 @@ import type { Client as SSHClient } from "ssh2";
|
||||
import { execElevated } from "@termix/plugin-sdk/host-commands";
|
||||
import type {
|
||||
PluginHostCreateInput,
|
||||
PluginHostRecord,
|
||||
PluginHostJumpHost,
|
||||
PluginHostUpdateInput,
|
||||
PluginSshHost,
|
||||
} from "@termix/plugin-sdk/backend";
|
||||
import { connectSsh } from "./ssh.js";
|
||||
import { pluginCtx } from "./plugin-ctx.js";
|
||||
import { resolveProxmoxImportAuth } from "./proxmox-import-auth.js";
|
||||
import {
|
||||
parseProxmoxJumpHosts,
|
||||
serializeProxmoxJumpHosts,
|
||||
} from "./proxmox-jump-hosts.js";
|
||||
import { parseProxmoxJumpHosts } from "./proxmox-jump-hosts.js";
|
||||
import { isSafeNodeName } from "./proxmox-shared.js";
|
||||
import {
|
||||
indexImportedGuests,
|
||||
@@ -190,7 +188,7 @@ type ProxmoxGuest = {
|
||||
};
|
||||
|
||||
/** The resolved host ctx.ssh.connect hands back, plus the sudo secret proxmox needs for pvesh. */
|
||||
type PluginSshHostWithSudo = PluginHostRecord & { sudoPassword?: string };
|
||||
type PluginSshHostWithSudo = PluginSshHost & { sudoPassword?: string };
|
||||
|
||||
type ProxmoxSyncResult = {
|
||||
created: number;
|
||||
@@ -215,6 +213,22 @@ function guestTags(guest: ProxmoxGuest): string[] {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The switches another plugin keeps for an imported guest. An entry for a
|
||||
* plugin that is not running is skipped by core.
|
||||
*/
|
||||
export function guestPluginSettings(
|
||||
connectionType: "ssh" | "rdp",
|
||||
enableDocker: boolean,
|
||||
): Record<string, Record<string, unknown>> {
|
||||
return {
|
||||
...(connectionType === "rdp"
|
||||
? { "remote-desktop": { enableRdp: true, rdpPort: 3389 } }
|
||||
: {}),
|
||||
...(enableDocker ? { docker: { enableDocker: true } } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function mergeTags(
|
||||
existing: unknown,
|
||||
additions: string[],
|
||||
@@ -261,7 +275,7 @@ async function discoverProxmoxGuestsForHost(
|
||||
timeoutMs: 35000,
|
||||
overrides: { tryKeyboard: false, readyTimeout: 30000 },
|
||||
});
|
||||
const hostWithSudo = host as PluginSshHostWithSudo;
|
||||
const hostWithSudo: PluginSshHostWithSudo = host;
|
||||
const hostCredentialId = (hostWithSudo.credentialId as number | null) ?? null;
|
||||
|
||||
try {
|
||||
@@ -498,7 +512,7 @@ async function syncProxmoxHost(
|
||||
|
||||
try {
|
||||
const discovery = await discoverProxmoxGuestsForHost(userId, sourceHostId);
|
||||
const sourceHostName = discovery.host.name || "Proxmox";
|
||||
const sourceHostName = String(discovery.host.name || "Proxmox");
|
||||
const defaultCredentialId =
|
||||
discovery.config.defaultCredentialId ?? discovery.credentialId ?? null;
|
||||
const importAuth = resolveProxmoxImportAuth(
|
||||
@@ -507,12 +521,8 @@ async function syncProxmoxHost(
|
||||
);
|
||||
const now = new Date().toISOString();
|
||||
|
||||
const existingHosts = (await ctx.hosts.listOwned()) as unknown as Record<
|
||||
string,
|
||||
unknown
|
||||
>[];
|
||||
const existingBySource = indexImportedGuests(
|
||||
existingHosts,
|
||||
await ctx.hosts.listOwned(),
|
||||
await ctx.settings.listHostValues("proxmoxConfig"),
|
||||
sourceHostId,
|
||||
);
|
||||
@@ -560,7 +570,7 @@ async function syncProxmoxHost(
|
||||
: connectionType === "rdp"
|
||||
? ""
|
||||
: "root";
|
||||
const update: Record<string, unknown> = {
|
||||
const update: PluginHostUpdateInput = {
|
||||
name: guest.name,
|
||||
ip: guest.ip || existing?.ip || "0.0.0.0",
|
||||
port,
|
||||
@@ -568,7 +578,7 @@ async function syncProxmoxHost(
|
||||
connectionType,
|
||||
folder: existing?.folder || sourceHostName,
|
||||
tags: mergeTags(existing?.tags, guestTags(guest), ["proxmox-missing"]),
|
||||
updatedAt: now,
|
||||
pluginSettings: { [ctx.pluginId]: { proxmoxConfig } },
|
||||
};
|
||||
|
||||
if (existing) {
|
||||
@@ -576,69 +586,46 @@ async function syncProxmoxHost(
|
||||
update.credentialId = importAuth.credentialId;
|
||||
update.overrideCredentialUsername = false;
|
||||
}
|
||||
await ctx.hosts.update(
|
||||
existing.id as number,
|
||||
update as PluginHostUpdateInput,
|
||||
);
|
||||
await ctx.settings.setHost(
|
||||
existing.id as number,
|
||||
"proxmoxConfig",
|
||||
proxmoxConfig,
|
||||
);
|
||||
await ctx.hosts.update(existing.id, update);
|
||||
result.updated++;
|
||||
continue;
|
||||
}
|
||||
|
||||
Object.assign(update, {
|
||||
enableDocker: guest.enableDocker,
|
||||
enableSsh: connectionType === "ssh",
|
||||
enableRdp: connectionType === "rdp",
|
||||
});
|
||||
|
||||
const created = await ctx.hosts.create({
|
||||
await ctx.hosts.create({
|
||||
...update,
|
||||
createdAt: now,
|
||||
name: guest.name,
|
||||
ip: update.ip!,
|
||||
port,
|
||||
username,
|
||||
enableSsh: connectionType === "ssh",
|
||||
pin: false,
|
||||
authType: connectionType === "rdp" ? "password" : importAuth.authType,
|
||||
credentialId: connectionType === "ssh" ? importAuth.credentialId : null,
|
||||
overrideCredentialUsername: importAuth.overrideCredentialUsername,
|
||||
password: null,
|
||||
key: null,
|
||||
keyPassword: null,
|
||||
keyType: null,
|
||||
rdpPort: connectionType === "rdp" ? 3389 : null,
|
||||
jumpHosts: serializeProxmoxJumpHosts(discovery.jumpHosts),
|
||||
quickActions: null,
|
||||
forceKeyboardInteractive: "false",
|
||||
useSocks5: 0,
|
||||
socks5Host: null,
|
||||
socks5Port: null,
|
||||
socks5Username: null,
|
||||
socks5Password: null,
|
||||
socks5ProxyChain: null,
|
||||
portKnockSequence: null,
|
||||
} as unknown as PluginHostCreateInput);
|
||||
await ctx.settings.setHost(
|
||||
Number(created.id),
|
||||
"proxmoxConfig",
|
||||
proxmoxConfig,
|
||||
);
|
||||
overrideCredentialUsername: !!importAuth.overrideCredentialUsername,
|
||||
jumpHosts: (parseProxmoxJumpHosts(discovery.jumpHosts) ??
|
||||
[]) as PluginHostJumpHost[],
|
||||
forceKeyboardInteractive: false,
|
||||
pluginSettings: {
|
||||
...update.pluginSettings,
|
||||
...guestPluginSettings(connectionType, guest.enableDocker),
|
||||
},
|
||||
});
|
||||
result.created++;
|
||||
}
|
||||
|
||||
if (discovery.config.markMissingGuests) {
|
||||
for (const [key, { host, config, source }] of existingBySource) {
|
||||
if (seen.has(key)) continue;
|
||||
await ctx.hosts.update(
|
||||
host.id as number,
|
||||
{
|
||||
tags: mergeTags(host.tags, ["proxmox-missing"]),
|
||||
updatedAt: now,
|
||||
} as PluginHostUpdateInput,
|
||||
);
|
||||
await ctx.settings.setHost(host.id as number, "proxmoxConfig", {
|
||||
...config,
|
||||
source: { ...source, missingSince: source.missingSince || now },
|
||||
await ctx.hosts.update(host.id, {
|
||||
tags: mergeTags(host.tags, ["proxmox-missing"]),
|
||||
pluginSettings: {
|
||||
[ctx.pluginId]: {
|
||||
proxmoxConfig: {
|
||||
...config,
|
||||
source: { ...source, missingSince: source.missingSince || now },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
result.markedMissing++;
|
||||
}
|
||||
@@ -984,22 +971,15 @@ router.post("/import", async (req, res) => {
|
||||
return res.status(400).json({ error: "No hosts to import" });
|
||||
}
|
||||
const result = { success: 0, failed: 0, errors: [] as string[] };
|
||||
for (const entry of hosts as Array<Record<string, unknown>>) {
|
||||
const { pluginSettings, ...input } = entry;
|
||||
for (const entry of hosts as PluginHostCreateInput[]) {
|
||||
try {
|
||||
const created = await ctx.hosts.create(
|
||||
input as unknown as PluginHostCreateInput,
|
||||
);
|
||||
const own = (pluginSettings as Record<string, unknown> | undefined)?.[
|
||||
ctx.pluginId
|
||||
] as Record<string, unknown> | undefined;
|
||||
for (const [key, value] of Object.entries(own ?? {})) {
|
||||
await ctx.settings.setHost(Number(created.id), key, value);
|
||||
}
|
||||
// Core refuses any field it does not take, and any host setting its
|
||||
// plugin does not declare.
|
||||
await ctx.hosts.create(entry);
|
||||
result.success++;
|
||||
} catch (err: unknown) {
|
||||
result.failed++;
|
||||
result.errors.push(`${String(input.name)}: ${getErrorMessage(err)}`);
|
||||
result.errors.push(`${String(entry?.name)}: ${getErrorMessage(err)}`);
|
||||
}
|
||||
}
|
||||
return res.json(result);
|
||||
|
||||
@@ -158,8 +158,6 @@ export function ProxmoxDiscoverDialog({
|
||||
jumpHosts: discoveredJumpHosts ?? undefined,
|
||||
...importAuth,
|
||||
enableSsh: g.connectionType !== "rdp",
|
||||
enableRdp: g.connectionType === "rdp",
|
||||
enableDocker: g.enableDocker,
|
||||
connectionType: g.connectionType,
|
||||
tags: [
|
||||
"proxmox",
|
||||
@@ -168,8 +166,13 @@ export function ProxmoxDiscoverDialog({
|
||||
g.type === "lxc" ? `ct-${g.vmid}` : `vm-${g.vmid}`,
|
||||
...(g.enableDocker ? ["docker"] : []),
|
||||
],
|
||||
// This plugin's host settings travel with the import like an export's.
|
||||
// Host settings travel with the import like an export's, keyed by
|
||||
// the plugin that keeps them.
|
||||
pluginSettings: {
|
||||
...(g.connectionType === "rdp"
|
||||
? { "remote-desktop": { enableRdp: true, rdpPort: 3389 } }
|
||||
: {}),
|
||||
...(g.enableDocker ? { docker: { enableDocker: true } } : {}),
|
||||
proxmox: {
|
||||
proxmoxConfig: {
|
||||
source: {
|
||||
|
||||
@@ -92,6 +92,13 @@ function ProxmoxStatsStandalone({ hostId }: StandaloneViewProps) {
|
||||
return <ProxmoxStatsApp hostId={hostId} />;
|
||||
}
|
||||
|
||||
/** This plugin's host settings, as they arrive on the host record. */
|
||||
export function proxmoxSettings(
|
||||
host: Pick<PluginHostRecord, "pluginSettings">,
|
||||
): Record<string, unknown> {
|
||||
return host.pluginSettings?.proxmox ?? {};
|
||||
}
|
||||
|
||||
export function activate(app: TermixApp): void {
|
||||
setProxmoxApp(app);
|
||||
app.onDispose(() => setProxmoxApp(null));
|
||||
@@ -136,7 +143,7 @@ export function activate(app: TermixApp): void {
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
onClick={() => openDiscover({})}
|
||||
disabled={!hosts.some((host) => host.enableProxmox)}
|
||||
disabled={!hosts.some((host) => proxmoxSettings(host).enableProxmox)}
|
||||
>
|
||||
<Server className="size-3.5 mr-2" />
|
||||
{t("hosts.proxmoxImportTitle")}
|
||||
@@ -166,9 +173,9 @@ export function activate(app: TermixApp): void {
|
||||
icon: Boxes,
|
||||
kind: "open",
|
||||
order: 90,
|
||||
when: (host) => !!host.enableProxmox,
|
||||
when: (host) => !!proxmoxSettings(host).enableProxmox,
|
||||
run: (host) => {
|
||||
const config = host.proxmoxConfig as
|
||||
const config = proxmoxSettings(host).proxmoxConfig as
|
||||
| { defaultCredentialId?: number | null; defaultAuthType?: string }
|
||||
| undefined;
|
||||
openDiscover({
|
||||
@@ -205,6 +212,6 @@ export function activate(app: TermixApp): void {
|
||||
order: 60,
|
||||
tabType: "proxmox-stats",
|
||||
copyUrlView: "proxmox-stats",
|
||||
when: (host) => host.enableProxmoxStats === true,
|
||||
when: (host) => proxmoxSettings(host).enableProxmoxStats === true,
|
||||
});
|
||||
}
|
||||
@@ -1,26 +1,14 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
parseProxmoxJumpHosts,
|
||||
serializeProxmoxJumpHosts,
|
||||
} from "../../src/backend/proxmox-jump-hosts.js";
|
||||
import { parseProxmoxJumpHosts } from "../../src/backend/proxmox-jump-hosts.js";
|
||||
|
||||
describe("Proxmox jump-host persistence", () => {
|
||||
const jumpHosts = [{ hostId: 7 }, { hostId: 9 }];
|
||||
|
||||
it("serializes resolved arrays before inserting a synced guest", () => {
|
||||
expect(serializeProxmoxJumpHosts(jumpHosts)).toBe(
|
||||
'[{"hostId":7},{"hostId":9}]',
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps stored JSON strings stable", () => {
|
||||
const stored = '[{"hostId":7}]';
|
||||
expect(serializeProxmoxJumpHosts(stored)).toBe(stored);
|
||||
expect(parseProxmoxJumpHosts(stored)).toEqual([{ hostId: 7 }]);
|
||||
it("reads a resolved array or a stored JSON string", () => {
|
||||
expect(parseProxmoxJumpHosts([{ hostId: 7 }])).toEqual([{ hostId: 7 }]);
|
||||
expect(parseProxmoxJumpHosts('[{"hostId":7}]')).toEqual([{ hostId: 7 }]);
|
||||
});
|
||||
|
||||
it("turns missing or malformed values into null", () => {
|
||||
expect(serializeProxmoxJumpHosts(null)).toBeNull();
|
||||
expect(serializeProxmoxJumpHosts("invalid")).toBeNull();
|
||||
expect(parseProxmoxJumpHosts(null)).toBeNull();
|
||||
expect(parseProxmoxJumpHosts("invalid")).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { guestPluginSettings } from "../../src/backend/routes.js";
|
||||
|
||||
describe("guestPluginSettings", () => {
|
||||
it("names the plugin that keeps each switch an imported guest needs", () => {
|
||||
expect(guestPluginSettings("rdp", true)).toEqual({
|
||||
"remote-desktop": { enableRdp: true, rdpPort: 3389 },
|
||||
docker: { enableDocker: true },
|
||||
});
|
||||
expect(guestPluginSettings("ssh", false)).toEqual({});
|
||||
});
|
||||
});
|
||||
@@ -38,6 +38,25 @@ describe(`${manifest.id} activate`, () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("reads its switches from its own host settings", async () => {
|
||||
rendered = await renderWithApp(plugin, { manifest, locales });
|
||||
const host = (settings: Record<string, unknown>) => ({
|
||||
id: "1",
|
||||
name: "pve",
|
||||
ip: "10.0.0.1",
|
||||
port: 22,
|
||||
pluginSettings: { proxmox: settings },
|
||||
});
|
||||
const ids = (settings: Record<string, unknown>) =>
|
||||
rendered!.registered.hostActionsFor(host(settings)).map((a) => a.id);
|
||||
expect(ids({ enableProxmox: true })).toContain("proxmox-discover");
|
||||
expect(ids({})).not.toContain("proxmox-discover");
|
||||
expect(ids({ enableProxmoxStats: true })).toContain("proxmox-stats");
|
||||
expect(plugin.proxmoxSettings(host({ enableProxmoxStats: true }))).toEqual({
|
||||
enableProxmoxStats: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("removes everything it registered on deactivate", async () => {
|
||||
const app = await renderWithApp(plugin, { manifest, locales });
|
||||
await app.deactivate();
|
||||
|
||||
Reference in new issue
Block a user