345 lines
14 KiB
JavaScript
345 lines
14 KiB
JavaScript
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');
|