summaryrefslogtreecommitdiffstats
path: root/static/systemd-network.js
diff options
context:
space:
mode:
Diffstat (limited to 'static/systemd-network.js')
-rw-r--r--static/systemd-network.js590
1 files changed, 277 insertions, 313 deletions
diff --git a/static/systemd-network.js b/static/systemd-network.js
index 8c66a6d..1a33f0e 100644
--- a/static/systemd-network.js
+++ b/static/systemd-network.js
@@ -7,56 +7,71 @@
*/
/**
- * MAC Address type
- * @class MACAddress
+ * Base field type with standardized interface
+ * @class BaseField
*/
-class MACAddress {
+class BaseField {
/**
- * @param {string} value - MAC address value
- * @param {string} description - Description
+ * @param {*} value - Field value
+ * @param {string} type - Field type
+ * @param {string} description - Field description
+ * @param {Object} options - Additional options (pattern, enum, etc.)
*/
- constructor(value = '', description = 'Hardware address') {
+ constructor(value = null, type = 'string', description = '', options = {}) {
this.value = value;
- this.type = 'mac-address';
+ this.type = type;
this.description = description;
- this.pattern = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
+ this.options = options;
}
/**
- * Validate MAC address format
+ * Validate field value
* @returns {boolean}
*/
validate() {
- return this.pattern.test(this.value);
+ if (this.value === null || this.value === undefined) return true;
+
+ if (this.options.pattern && typeof this.value === 'string') {
+ return this.options.pattern.test(this.value);
+ }
+
+ if (this.options.enum && this.options.enum.length > 0) {
+ return this.options.enum.includes(this.value);
+ }
+
+ return true;
}
+ /**
+ * Convert to string representation
+ * @returns {string}
+ */
toString() {
- return this.value;
+ return this.value !== null ? String(this.value) : '';
}
}
/**
- * IPv4 Address type
- * @class IPv4Address
+ * MAC Address type
+ * @class MACAddress
*/
-class IPv4Address {
- /**
- * @param {string} value - IPv4 address
- * @param {string} description - Description
- */
- constructor(value = '', description = 'IPv4 address') {
- this.value = value;
- this.type = 'ipv4-address';
- this.description = description;
- this.pattern = /^(\d{1,3}\.){3}\d{1,3}$/;
- }
-
- validate() {
- return this.pattern.test(this.value);
+class MACAddress extends BaseField {
+ constructor(value = null) {
+ super(value, 'mac-address', 'Hardware address (MAC)', {
+ pattern: /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/
+ });
}
+}
- toString() {
- return this.value;
+/**
+ * IPv4 Address type
+ * @class IPv4Address
+ */
+class IPv4Address extends BaseField {
+ constructor(value = null) {
+ super(value, 'ipv4-address', 'IPv4 address', {
+ pattern: /^(\d{1,3}\.){3}\d{1,3}$/
+ });
}
}
@@ -64,24 +79,47 @@ class IPv4Address {
* IPv6 Address type
* @class IPv6Address
*/
-class IPv6Address {
- /**
- * @param {string} value - IPv6 address
- * @param {string} description - Description
- */
- constructor(value = '', description = 'IPv6 address') {
- this.value = value;
- this.type = 'ipv6-address';
- this.description = description;
- this.pattern = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
+class IPv6Address extends BaseField {
+ constructor(value = null) {
+ super(value, 'ipv6-address', 'IPv6 address', {
+ pattern: /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/
+ });
}
+}
- validate() {
- return this.pattern.test(this.value);
+/**
+ * Boolean type with yes/no values
+ * @class BooleanYesNo
+ */
+class BooleanYesNo extends BaseField {
+ constructor(value = null) {
+ super(value, 'boolean', 'Boolean (yes/no)', {
+ enum: ['yes', 'no']
+ });
}
+}
- toString() {
- return this.value;
+/**
+ * Port type
+ * @class Port
+ */
+class Port extends BaseField {
+ constructor(value = null) {
+ super(value, 'port', 'Network port (1-65535)', {
+ pattern: /^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/
+ });
+ }
+}
+
+/**
+ * MTU type
+ * @class MTU
+ */
+class MTU extends BaseField {
+ constructor(value = null) {
+ super(value, 'mtu', 'Maximum Transmission Unit', {
+ pattern: /^[1-9][0-9]*$/
+ });
}
}
@@ -91,28 +129,17 @@ class IPv6Address {
*/
class MatchSection {
constructor() {
- /** @type {MACAddress[]} */
- this.MACAddress = [];
- /** @type {string[]} */
- this.OriginalName = [];
- /** @type {string[]} */
- this.Path = [];
- /** @type {string[]} */
- this.Driver = [];
- /** @type {string[]} */
- this.Type = [];
- /** @type {string[]} */
- this.Name = [];
- /** @type {string} */
- this.Property = '';
- /** @type {string} */
- this.Host = '';
- /** @type {string} */
- this.Virtualization = '';
- /** @type {string} */
- this.KernelCommandLine = '';
- /** @type {string} */
- this.Architecture = '';
+ this.MACAddress = new BaseField(null, 'mac-addresses', 'Space-separated MAC addresses');
+ this.OriginalName = new BaseField(null, 'strings', 'Original interface names');
+ this.Path = new BaseField(null, 'strings', 'Device path patterns');
+ this.Driver = new BaseField(null, 'strings', 'Driver names');
+ this.Type = new BaseField(null, 'strings', 'Interface types (ether, wifi, etc.)');
+ this.Name = new BaseField(null, 'strings', 'Interface names');
+ this.Property = new BaseField(null, 'string', 'Device property');
+ this.Host = new BaseField(null, 'string', 'Host name');
+ this.Virtualization = new BaseField(null, 'string', 'Virtualization detection');
+ this.KernelCommandLine = new BaseField(null, 'string', 'Kernel command line');
+ this.Architecture = new BaseField(null, 'string', 'System architecture');
}
}
@@ -122,26 +149,22 @@ class MatchSection {
*/
class LinkSection {
constructor() {
- /** @type {string} */
- this.MACAddress = '';
- /** @type {string} */
- this.MTUBytes = '';
- /** @type {number} */
- this.BitsPerSecond = 0;
- /** @type {string} */
- this.Duplex = '';
- /** @type {string} */
- this.AutoNegotiation = '';
- /** @type {string} */
- this.WakeOnLan = '';
- /** @type {string} */
- this.Port = '';
- /** @type {string} */
- this.Advertise = '';
- /** @type {string} */
- this.RxFlowControl = '';
- /** @type {string} */
- this.TxFlowControl = '';
+ this.MACAddress = new MACAddress();
+ this.MTUBytes = new MTU();
+ this.BitsPerSecond = new BaseField(null, 'number', 'Link speed in bits per second');
+ this.Duplex = new BaseField(null, 'string', 'Duplex mode', {
+ enum: ['half', 'full']
+ });
+ this.AutoNegotiation = new BooleanYesNo();
+ this.WakeOnLan = new BaseField(null, 'string', 'Wake-on-LAN', {
+ enum: ['phy', 'unicast', 'broadcast', 'arp', 'magic', '']
+ });
+ this.Port = new BaseField(null, 'string', 'Port type', {
+ enum: ['tp', 'aui', 'bnc', 'mii', 'fibre', '']
+ });
+ this.Advertise = new BaseField(null, 'strings', 'Advertised features');
+ this.RxFlowControl = new BooleanYesNo();
+ this.TxFlowControl = new BooleanYesNo();
}
}
@@ -151,36 +174,33 @@ class LinkSection {
*/
class NetworkSection {
constructor() {
- /** @type {string} */
- this.Description = '';
- /** @type {string[]} */
- this.DHCP = []; // 'yes', 'no', 'ipv4', 'ipv6'
- /** @type {boolean} */
- this.DHCPServer = false;
- /** @type {string[]} */
- this.DNS = [];
- /** @type {string[]} */
- this.NTP = [];
- /** @type {string[]} */
- this.IPForward = []; // 'yes', 'no', 'ipv4', 'ipv6'
- /** @type {string} */
- this.IPv6PrivacyExtensions = ''; // 'yes', 'no', 'prefer-public'
- /** @type {string} */
- this.IPv6AcceptRA = ''; // 'yes', 'no'
- /** @type {string} */
- this.LLMNR = ''; // 'yes', 'no', 'resolve'
- /** @type {string} */
- this.MulticastDNS = ''; // 'yes', 'no', 'resolve'
- /** @type {string} */
- this.DNSSEC = ''; // 'yes', 'no', 'allow-downgrade'
- /** @type {string[]} */
- this.Domains = [];
- /** @type {string} */
- this.ConfigureWithoutCarrier = ''; // 'yes', 'no'
- /** @type {string} */
- this.IgnoreCarrierLoss = ''; // 'yes', 'no'
- /** @type {number} */
- this.KeepConfiguration = 0; // seconds
+ this.Description = new BaseField(null, 'string', 'Interface description');
+ this.DHCP = new BaseField(null, 'dhcp-mode', 'DHCP client', {
+ enum: ['yes', 'no', 'ipv4', 'ipv6']
+ });
+ this.DHCPServer = new BooleanYesNo();
+ this.DNS = new BaseField(null, 'ip-addresses', 'DNS servers');
+ this.NTP = new BaseField(null, 'ip-addresses', 'NTP servers');
+ this.IPForward = new BaseField(null, 'ip-forward', 'IP forwarding', {
+ enum: ['yes', 'no', 'ipv4', 'ipv6']
+ });
+ this.IPv6PrivacyExtensions = new BaseField(null, 'privacy-extensions', 'IPv6 privacy extensions', {
+ enum: ['yes', 'no', 'prefer-public']
+ });
+ this.IPv6AcceptRA = new BooleanYesNo();
+ this.LLMNR = new BaseField(null, 'llmnr', 'LLMNR support', {
+ enum: ['yes', 'no', 'resolve']
+ });
+ this.MulticastDNS = new BaseField(null, 'mdns', 'Multicast DNS', {
+ enum: ['yes', 'no', 'resolve']
+ });
+ this.DNSSEC = new BaseField(null, 'dnssec', 'DNSSEC support', {
+ enum: ['yes', 'no', 'allow-downgrade']
+ });
+ this.Domains = new BaseField(null, 'strings', 'DNS search domains');
+ this.ConfigureWithoutCarrier = new BooleanYesNo();
+ this.IgnoreCarrierLoss = new BooleanYesNo();
+ this.KeepConfiguration = new BaseField(null, 'number', 'Keep configuration time in seconds');
}
}
@@ -190,20 +210,17 @@ class NetworkSection {
*/
class DHCPSection {
constructor() {
- /** @type {string} */
- this.UseDNS = ''; // 'yes', 'no'
- /** @type {string} */
- this.UseNTP = ''; // 'yes', 'no'
- /** @type {string} */
- this.UseMTU = ''; // 'yes', 'no'
- /** @type {string} */
- this.UseHostname = ''; // 'yes', 'no'
- /** @type {string} */
- this.UseDomains = ''; // 'yes', 'no', 'route'
- /** @type {string} */
- this.ClientIdentifier = ''; // 'mac', 'duid'
- /** @type {string} */
- this.RouteMetric = '';
+ this.UseDNS = new BooleanYesNo();
+ this.UseNTP = new BooleanYesNo();
+ this.UseMTU = new BooleanYesNo();
+ this.UseHostname = new BooleanYesNo();
+ this.UseDomains = new BaseField(null, 'use-domains', 'Use domains from DHCP', {
+ enum: ['yes', 'no', 'route']
+ });
+ this.ClientIdentifier = new BaseField(null, 'client-identifier', 'DHCP client identifier', {
+ enum: ['mac', 'duid']
+ });
+ this.RouteMetric = new BaseField(null, 'number', 'Route metric for DHCP routes');
}
}
@@ -213,18 +230,12 @@ class DHCPSection {
*/
class AddressSection {
constructor() {
- /** @type {string} */
- this.Address = ''; // IP address with prefix
- /** @type {string} */
- this.Peer = ''; // Peer address
- /** @type {string} */
- this.Broadcast = ''; // Broadcast address
- /** @type {string} */
- this.Label = ''; // Address label
- /** @type {number} */
- this.Scope = 0; // Address scope
- /** @type {string} */
- this.Flags = ''; // Address flags
+ this.Address = new BaseField(null, 'ip-prefix', 'IP address with prefix');
+ this.Peer = new BaseField(null, 'ip-address', 'Peer address');
+ this.Broadcast = new BaseField(null, 'ip-address', 'Broadcast address');
+ this.Label = new BaseField(null, 'string', 'Address label');
+ this.Scope = new BaseField(null, 'number', 'Address scope');
+ this.Flags = new BaseField(null, 'strings', 'Address flags');
}
}
@@ -234,22 +245,18 @@ class AddressSection {
*/
class RouteSection {
constructor() {
- /** @type {string} */
- this.Gateway = ''; // Gateway address
- /** @type {string} */
- this.GatewayOnLink = ''; // 'yes', 'no'
- /** @type {string} */
- this.Destination = ''; // Destination prefix
- /** @type {string} */
- this.Source = ''; // Source address
- /** @type {string} */
- this.PreferredSource = ''; // Preferred source address
- /** @type {number} */
- this.Metric = 1024; // Route metric
- /** @type {string} */
- this.Scope = ''; // 'global', 'link', 'host'
- /** @type {string} */
- this.Type = ''; // 'unicast', 'local', 'broadcast', etc.
+ this.Gateway = new BaseField(null, 'ip-address', 'Gateway address');
+ this.GatewayOnLink = new BooleanYesNo();
+ this.Destination = new BaseField(null, 'ip-prefix', 'Destination prefix');
+ this.Source = new BaseField(null, 'ip-address', 'Source address');
+ this.PreferredSource = new BaseField(null, 'ip-address', 'Preferred source address');
+ this.Metric = new BaseField(null, 'number', 'Route metric');
+ this.Scope = new BaseField(null, 'route-scope', 'Route scope', {
+ enum: ['global', 'link', 'host']
+ });
+ this.Type = new BaseField(null, 'route-type', 'Route type', {
+ enum: ['unicast', 'local', 'broadcast', 'anycast', 'multicast', 'blackhole', 'unreachable', 'prohibit']
+ });
}
}
@@ -259,21 +266,64 @@ class RouteSection {
*/
class NetworkConfiguration {
constructor() {
- /** @type {MatchSection} */
this.Match = new MatchSection();
- /** @type {LinkSection} */
this.Link = new LinkSection();
- /** @type {NetworkSection} */
this.Network = new NetworkSection();
- /** @type {DHCPSection} */
this.DHCP = new DHCPSection();
- /** @type {AddressSection[]} */
this.Address = [];
- /** @type {RouteSection[]} */
this.Route = [];
}
/**
+ * Get schema for structured editor
+ * @returns {Object} Schema definition
+ */
+ getSchema() {
+ return {
+ Match: this._getSectionSchema(this.Match),
+ Link: this._getSectionSchema(this.Link),
+ Network: this._getSectionSchema(this.Network),
+ DHCP: this._getSectionSchema(this.DHCP),
+ Address: this._getArraySectionSchema(AddressSection, 'Address'),
+ Route: this._getArraySectionSchema(RouteSection, 'Route')
+ };
+ }
+
+ /**
+ * Get schema for a single section
+ * @private
+ * @param {Object} section - Section instance
+ * @returns {Object} Section schema
+ */
+ _getSectionSchema(section) {
+ const schema = {};
+ for (const [key, field] of Object.entries(section)) {
+ schema[key] = {
+ value: field.value,
+ type: field.type,
+ description: field.description,
+ options: field.options
+ };
+ }
+ return schema;
+ }
+
+ /**
+ * Get schema for array sections (Address, Route)
+ * @private
+ * @param {Class} SectionClass - Section class
+ * @param {string} sectionName - Section name
+ * @returns {Object} Array section schema
+ */
+ _getArraySectionSchema(SectionClass, sectionName) {
+ const template = new SectionClass();
+ return {
+ itemSchema: this._getSectionSchema(template),
+ items: this[sectionName].map(item => this._getSectionSchema(item))
+ };
+ }
+
+ /**
* Parse systemd network configuration from text
* @param {string} configText - Configuration file content
* @returns {NetworkConfiguration}
@@ -282,6 +332,8 @@ class NetworkConfiguration {
const config = new NetworkConfiguration();
const lines = configText.split('\n');
let currentSection = null;
+ let currentAddress = null;
+ let currentRoute = null;
for (const line of lines) {
const trimmed = line.trim();
@@ -293,6 +345,15 @@ class NetworkConfiguration {
const sectionMatch = trimmed.match(/^\[(\w+)\]$/);
if (sectionMatch) {
currentSection = sectionMatch[1].toLowerCase();
+
+ // Start new array sections
+ if (currentSection === 'address') {
+ currentAddress = new AddressSection();
+ config.Address.push(currentAddress);
+ } else if (currentSection === 'route') {
+ currentRoute = new RouteSection();
+ config.Route.push(currentRoute);
+ }
continue;
}
@@ -302,7 +363,7 @@ class NetworkConfiguration {
const key = kvMatch[1];
const value = kvMatch[2];
- config._setValue(currentSection, key, value);
+ config._setValue(currentSection, key, value, currentAddress, currentRoute);
}
}
@@ -315,8 +376,10 @@ class NetworkConfiguration {
* @param {string} section - Section name
* @param {string} key - Key name
* @param {string} value - Value
+ * @param {AddressSection} currentAddress - Current address section
+ * @param {RouteSection} currentRoute - Current route section
*/
- _setValue(section, key, value) {
+ _setValue(section, key, value, currentAddress, currentRoute) {
switch (section) {
case 'match':
this._setMatchValue(key, value);
@@ -331,70 +394,52 @@ class NetworkConfiguration {
this._setDHCPValue(key, value);
break;
case 'address':
- // Handle multiple address sections
- if (!this.Address.length) this.Address.push(new AddressSection());
- this._setAddressValue(this.Address[this.Address.length - 1], key, value);
+ if (currentAddress) {
+ this._setAddressValue(currentAddress, key, value);
+ }
break;
case 'route':
- // Handle multiple route sections
- if (!this.Route.length) this.Route.push(new RouteSection());
- this._setRouteValue(this.Route[this.Route.length - 1], key, value);
+ if (currentRoute) {
+ this._setRouteValue(currentRoute, key, value);
+ }
break;
}
}
_setMatchValue(key, value) {
- const match = this.Match;
- switch (key) {
- case 'MACAddress':
- match.MACAddress = value.split(' ');
- break;
- case 'Name':
- match.Name = value.split(' ');
- break;
- case 'Driver':
- match.Driver = value.split(' ');
- break;
- case 'Path':
- match.Path = value.split(' ');
- break;
- case 'Type':
- match.Type = value.split(' ');
- break;
- default:
- match[key] = value;
+ if (this.Match[key] !== undefined) {
+ this.Match[key].value = value;
}
}
_setLinkValue(key, value) {
- this.Link[key] = value;
+ if (this.Link[key] !== undefined) {
+ this.Link[key].value = value;
+ }
}
_setNetworkValue(key, value) {
- const network = this.Network;
- switch (key) {
- case 'DNS':
- case 'NTP':
- case 'Domains':
- case 'DHCP':
- case 'IPForward':
- network[key] = value.split(' ');
- break;
- default:
- network[key] = value;
+ if (this.Network[key] !== undefined) {
+ this.Network[key].value = value;
}
}
_setDHCPValue(key, value) {
- this.DHCP[key] = value;
+ if (this.DHCP[key] !== undefined) {
+ this.DHCP[key].value = value;
+ }
}
_setAddressValue(address, key, value) {
- address[key] = value;
+ if (address[key] !== undefined) {
+ address[key].value = value;
+ }
}
_setRouteValue(route, key, value) {
- route[key] = value;
+ if (route[key] !== undefined) {
+ route[key].value = value;
+ }
}
/**
@@ -405,155 +450,74 @@ class NetworkConfiguration {
const sections = [];
// [Match] section
- if (this._hasMatchValues()) {
+ if (this._hasSectionValues(this.Match)) {
sections.push('[Match]');
- sections.push(...this._formatMatchSection());
+ sections.push(...this._formatSection(this.Match));
}
// [Link] section
- if (this._hasLinkValues()) {
+ if (this._hasSectionValues(this.Link)) {
sections.push('[Link]');
- sections.push(...this._formatLinkSection());
+ sections.push(...this._formatSection(this.Link));
}
// [Network] section
- if (this._hasNetworkValues()) {
+ if (this._hasSectionValues(this.Network)) {
sections.push('[Network]');
- sections.push(...this._formatNetworkSection());
+ sections.push(...this._formatSection(this.Network));
}
// [DHCP] section
- if (this._hasDHCPValues()) {
+ if (this._hasSectionValues(this.DHCP)) {
sections.push('[DHCP]');
- sections.push(...this._formatDHCPSection());
+ sections.push(...this._formatSection(this.DHCP));
}
// [Address] sections
- this.Address.forEach((addr, index) => {
- if (this._hasAddressValues(addr)) {
+ this.Address.forEach(addr => {
+ if (this._hasSectionValues(addr)) {
sections.push('[Address]');
- sections.push(...this._formatAddressSection(addr));
+ sections.push(...this._formatSection(addr));
}
});
// [Route] sections
- this.Route.forEach((route, index) => {
- if (this._hasRouteValues(route)) {
+ this.Route.forEach(route => {
+ if (this._hasSectionValues(route)) {
sections.push('[Route]');
- sections.push(...this._formatRouteSection(route));
+ sections.push(...this._formatSection(route));
}
});
return sections.join('\n') + '\n';
}
- // Helper methods to check if sections have values
- _hasMatchValues() {
- return Object.values(this.Match).some(val =>
- val && (Array.isArray(val) ? val.length > 0 : val !== '')
+ _hasSectionValues(section) {
+ return Object.values(section).some(field =>
+ field.value !== null && field.value !== undefined && field.value !== ''
);
}
- _hasLinkValues() {
- return Object.values(this.Link).some(val => val && val !== '');
- }
-
- _hasNetworkValues() {
- return Object.values(this.Network).some(val =>
- val && (Array.isArray(val) ? val.length > 0 : val !== '')
- );
- }
-
- _hasDHCPValues() {
- return Object.values(this.DHCP).some(val => val && val !== '');
- }
-
- _hasAddressValues(addr) {
- return Object.values(addr).some(val => val && val !== '');
- }
-
- _hasRouteValues(route) {
- return Object.values(route).some(val => val && val !== '');
- }
-
- // Formatting methods
- _formatMatchSection() {
+ _formatSection(section) {
const lines = [];
- const match = this.Match;
-
- if (match.MACAddress.length) lines.push(`MACAddress=${match.MACAddress.join(' ')}`);
- if (match.Name.length) lines.push(`Name=${match.Name.join(' ')}`);
- if (match.Driver.length) lines.push(`Driver=${match.Driver.join(' ')}`);
- if (match.Path.length) lines.push(`Path=${match.Path.join(' ')}`);
- if (match.Type.length) lines.push(`Type=${match.Type.join(' ')}`);
- if (match.Property) lines.push(`Property=${match.Property}`);
-
- return lines;
- }
-
- _formatLinkSection() {
- const lines = [];
- const link = this.Link;
-
- Object.entries(link).forEach(([key, value]) => {
- if (value && value !== '') lines.push(`${key}=${value}`);
- });
-
- return lines;
- }
-
- _formatNetworkSection() {
- const lines = [];
- const network = this.Network;
-
- if (network.Description) lines.push(`Description=${network.Description}`);
- if (network.DHCP.length) lines.push(`DHCP=${network.DHCP.join(' ')}`);
- if (network.DNS.length) lines.push(`DNS=${network.DNS.join(' ')}`);
- if (network.NTP.length) lines.push(`NTP=${network.NTP.join(' ')}`);
- if (network.IPForward.length) lines.push(`IPForward=${network.IPForward.join(' ')}`);
- if (network.IPv6PrivacyExtensions) lines.push(`IPv6PrivacyExtensions=${network.IPv6PrivacyExtensions}`);
- if (network.LLMNR) lines.push(`LLMNR=${network.LLMNR}`);
-
- return lines;
- }
-
- _formatDHCPSection() {
- const lines = [];
- const dhcp = this.DHCP;
-
- Object.entries(dhcp).forEach(([key, value]) => {
- if (value && value !== '') lines.push(`${key}=${value}`);
- });
-
- return lines;
- }
-
- _formatAddressSection(addr) {
- const lines = [];
-
- Object.entries(addr).forEach(([key, value]) => {
- if (value && value !== '') lines.push(`${key}=${value}`);
- });
-
- return lines;
- }
-
- _formatRouteSection(route) {
- const lines = [];
-
- Object.entries(route).forEach(([key, value]) => {
- if (value && value !== '') lines.push(`${key}=${value}`);
- });
-
+ for (const [key, field] of Object.entries(section)) {
+ if (field.value !== null && field.value !== undefined && field.value !== '') {
+ lines.push(`${key}=${field.toString()}`);
+ }
+ }
return lines;
}
}
// Export classes
export {
+ BaseField,
MACAddress,
IPv4Address,
IPv6Address,
+ BooleanYesNo,
+ Port,
+ MTU,
MatchSection,
LinkSection,
NetworkSection,