Files
hNetplan/app.js
2026-02-18 11:38:06 +03:00

345 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const { createApp } = Vue;
createApp({
data() {
return {
currentLang: 'tr',
isDark: false,
// Translation dictionary
translations: {
tr: {
globalSettings: 'Genel Ayarlar',
renderer: 'Oluşturucu (Renderer)',
version: 'Netplan Sürümü',
ethernets: 'Ethernet Arayüzleri',
addEthernet: 'Ethernet Ekle',
wifis: 'Wi-Fi Arayüzleri',
addWifi: 'Wi-Fi Ekle',
bridges: 'Köprüler (Bridges)',
addBridge: 'Köprü Ekle',
bonds: 'Bağlar (Bonds)',
addBond: 'Bağ Ekle',
vlans: 'VLANlar',
addVlan: 'VLAN Ekle',
noInterfaces: 'Henüz arayüz eklenmedi.',
interfaceName: 'Arayüz Adı',
interfaces: 'Arayüzler (Interfaces)',
ipAddresses: 'IP Adresleri',
gateway4: 'Gateway (IPv4)',
nameservers: 'DNS Sunucuları',
commaSeparated: 'Virgülle ayrılmış (örn: 192.168.1.1, 8.8.8.8)',
advancedSettings: 'Gelişmiş Ayarlar',
routes: 'Statik Rotalar (Routes)',
downloadYaml: 'YAML İndir',
copyClipboard: 'Kopyala',
parameters: 'Parametreler',
mode: 'Mod',
id: 'ID',
link: 'Bağlantı (Link)',
instructions: 'Kurulum Talimatları',
step1: '1. Oluşturulan dosyayı kopyalayın veya indirin.',
step2: '2. Linux sunucunuzda aşağıdaki dizine dosyayı kaydedin (varsayılan dosya adı genellikle 00-installer-config.yaml veya 01-netcfg.yaml olabilir):',
step3: '3. Dosya izinlerini güvenli hale getirin:',
step4: '4. Yapılandırmayı test edin (Hata varsa geri alır):',
step5: '5. Eğer test başarılıysa yapılandırmayı uygulayın:',
note: 'Not: Netplan dosya isimleri alfabetik sıraya göre işlenir. Eski yapılandırma dosyalarını yedeklemeyi veya silmeyi unutmayın.'
},
en: {
globalSettings: 'Global Settings',
renderer: 'Renderer',
version: 'Netplan Version',
ethernets: 'Ethernet Interfaces',
addEthernet: 'Add Ethernet',
wifis: 'Wi-Fi Interfaces',
addWifi: 'Add Wi-Fi',
bridges: 'Bridges',
addBridge: 'Add Bridge',
bonds: 'Bonds',
addBond: 'Add Bond',
vlans: 'VLANs',
addVlan: 'Add VLAN',
noInterfaces: 'No interfaces added yet.',
interfaceName: 'Interface Name',
interfaces: 'Interfaces',
ipAddresses: 'IP Addresses',
gateway4: 'Gateway (IPv4)',
nameservers: 'Nameservers',
commaSeparated: 'Comma separated (e.g. 192.168.1.1, 8.8.8.8)',
advancedSettings: 'Advanced Settings',
routes: 'Static Routes',
wifis: 'Wi-Fi Interfaces',
addWifi: 'Add Wi-Fi',
noWifis: 'No Wi-Fi interfaces added yet.',
downloadYaml: 'Download YAML',
copyClipboard: 'Copy',
parameters: 'Parameters',
mode: 'Mode',
id: 'ID',
link: 'Link',
instructions: 'Installation Instructions',
step1: '1. Copy or download the generated file.',
step2: '2. Save the file to the following directory on your Linux server (default filename is usually 00-installer-config.yaml or 01-netcfg.yaml):',
step3: '3. Secure the file permissions:',
step4: '4. Test the configuration (Reverts on error):',
step5: '5. If the test is successful, apply the configuration:',
note: 'Note: Netplan processes files in alphabetical order. Remember to backup or remove old configuration files.'
}
},
// Configuration Model
config: {
version: 2,
renderer: 'networkd',
ethernets: [],
wifis: [],
bridges: [],
bonds: [],
vlans: []
}
}
},
computed: {
generatedYaml() {
const network = {
version: this.config.version,
renderer: this.config.renderer
};
// Helper to clean common fields
const processCommon = (item) => {
const obj = {};
// DHCP
if (item.dhcp4) {
obj.dhcp4 = true;
}
// Static IP & Gateway & DNS - only if not DHCP (usually, though netplan allows mixing but let's keep simple)
// Actually netplan allows addresses with dhcp4: true (e.g. static + dhcp). But let's follow the UI logic:
// if DHCP is unchecked, these fields are shown.
if (!item.dhcp4) {
if (item.addressesInput) {
obj.addresses = item.addressesInput.split(',').map(s => {
let addr = s.trim();
if (addr && !addr.includes('/')) {
addr += '/24'; // Default to /24 if missing
}
return addr;
}).filter(s => s);
}
if (item.nameserversInput) {
obj.nameservers = {
addresses: item.nameserversInput.split(',').map(s => s.trim()).filter(s => s)
};
}
}
// Advanced
if (item.mtu) obj.mtu = item.mtu;
if (item.macaddress) obj.macaddress = item.macaddress;
// Routes
let finalRoutes = [];
// Deprecated gateway4 -> converted to default route
if (!item.dhcp4 && item.gateway4) {
finalRoutes.push({ to: 'default', via: item.gateway4 });
}
// Custom Routes
if (item.routes && item.routes.length > 0) {
const validRoutes = item.routes.filter(r => r.to && r.via).map(r => ({ to: r.to, via: r.via }));
finalRoutes = finalRoutes.concat(validRoutes);
}
if (finalRoutes.length > 0) {
obj.routes = finalRoutes;
}
return obj;
};
// Ethernets
if (this.config.ethernets.length > 0) {
network.ethernets = {};
this.config.ethernets.forEach(eth => {
if (eth.name) {
network.ethernets[eth.name] = processCommon(eth);
}
});
}
// Wi-Fis
if (this.config.wifis.length > 0) {
network.wifis = {};
this.config.wifis.forEach(wifi => {
if (!wifi.name) return;
const obj = processCommon(wifi);
if (wifi.accessPoints && wifi.accessPoints.length > 0) {
obj['access-points'] = {};
wifi.accessPoints.forEach(ap => {
if (ap.ssid) {
obj['access-points'][ap.ssid] = {};
if (ap.password) {
obj['access-points'][ap.ssid].password = ap.password;
}
}
});
}
network.wifis[wifi.name] = obj;
});
}
// Bridges
if (this.config.bridges.length > 0) {
network.bridges = {};
this.config.bridges.forEach(bridge => {
if (!bridge.name) return;
const obj = processCommon(bridge);
if (bridge.interfacesInput) {
obj.interfaces = bridge.interfacesInput.split(',').map(s => s.trim()).filter(s => s);
}
if (bridge.parameters) {
obj.parameters = {};
if (bridge.parameters.stp !== null) obj.parameters.stp = bridge.parameters.stp;
if (bridge.parameters.forwardDelay !== null && bridge.parameters.forwardDelay !== '') obj.parameters['forward-delay'] = bridge.parameters.forwardDelay;
}
network.bridges[bridge.name] = obj;
});
}
// Bonds
if (this.config.bonds.length > 0) {
network.bonds = {};
this.config.bonds.forEach(bond => {
if (!bond.name) return;
const obj = processCommon(bond);
if (bond.interfacesInput) {
obj.interfaces = bond.interfacesInput.split(',').map(s => s.trim()).filter(s => s);
}
if (bond.parameters) {
obj.parameters = {};
if (bond.parameters.mode) obj.parameters.mode = bond.parameters.mode;
}
network.bonds[bond.name] = obj;
});
}
// VLANs
if (this.config.vlans.length > 0) {
network.vlans = {};
this.config.vlans.forEach(vlan => {
if (!vlan.name) return;
const obj = processCommon(vlan);
if (vlan.id) obj.id = vlan.id;
if (vlan.link) obj.link = vlan.link;
network.vlans[vlan.name] = obj;
});
}
try {
// Using js-yaml from CDN
if (typeof jsyaml !== 'undefined') {
return jsyaml.dump({ network: network }, { indent: 2, noRefs: true });
} else {
return 'js-yaml library not loaded.';
}
} catch (e) {
return 'Error generating YAML: ' + e.message;
}
}
},
methods: {
t(key) {
return this.translations[this.currentLang][key] || key;
},
toggleLanguage() {
this.currentLang = this.currentLang === 'tr' ? 'en' : 'tr';
},
toggleTheme() {
this.isDark = !this.isDark;
if (this.isDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
},
createInterface(type) {
const base = {
dhcp4: true,
addressesInput: '',
gateway4: '',
nameserversInput: '',
mtu: null,
macaddress: '',
routes: [],
showAdvanced: false
};
if (type === 'ethernet') {
return { ...base, name: 'eth' + this.config.ethernets.length };
}
if (type === 'wifi') {
return { ...base, name: 'wlan' + this.config.wifis.length, accessPoints: [{ ssid: '', password: '' }] };
}
if (type === 'bridge') {
return { ...base, name: 'br' + this.config.bridges.length, interfacesInput: '', parameters: { stp: false, forwardDelay: 0 } };
}
if (type === 'bond') {
return { ...base, name: 'bond' + this.config.bonds.length, interfacesInput: '', parameters: { mode: 'active-backup' } };
}
if (type === 'vlan') {
return { ...base, name: 'vlan' + this.config.vlans.length, id: 10, link: '' };
}
},
addEthernet() {
this.config.ethernets.push(this.createInterface('ethernet'));
},
removeEthernet(index) {
this.config.ethernets.splice(index, 1);
},
addWifi() {
this.config.wifis.push(this.createInterface('wifi'));
},
removeWifi(index) {
this.config.wifis.splice(index, 1);
},
addBridge() {
this.config.bridges.push(this.createInterface('bridge'));
},
removeBridge(index) {
this.config.bridges.splice(index, 1);
},
addBond() {
this.config.bonds.push(this.createInterface('bond'));
},
removeBond(index) {
this.config.bonds.splice(index, 1);
},
addVlan() {
this.config.vlans.push(this.createInterface('vlan'));
},
removeVlan(index) {
this.config.vlans.splice(index, 1);
},
async copyToClipboard() {
try {
await navigator.clipboard.writeText(this.generatedYaml);
// alert('Kopyalandı!');
} catch (err) {
console.error('Failed to copy: ', err);
}
},
downloadYaml() {
const blob = new Blob([this.generatedYaml], { type: 'text/yaml' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '01-netcfg.yaml';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
},
mounted() {
this.addEthernet();
}
}).mount('#app');