diff options
-rw-r--r-- | interface-definitions/https.xml.in | 6 | ||||
-rw-r--r-- | python/vyos/configdict.py | 5 | ||||
-rw-r--r-- | python/vyos/configtree.py | 62 | ||||
-rw-r--r-- | python/vyos/ifconfig/wireless.py | 2 | ||||
-rw-r--r-- | python/vyos/ifconfig_vlan.py | 2 | ||||
-rw-r--r-- | python/vyos/migrator.py | 11 | ||||
-rwxr-xr-x | src/conf_mode/https.py | 18 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wireless.py | 5 | ||||
-rwxr-xr-x | src/helpers/run-config-migration.py | 19 | ||||
-rwxr-xr-x | src/helpers/vyos-load-config.py | 8 | ||||
-rwxr-xr-x | src/helpers/vyos-merge-config.py | 10 | ||||
-rw-r--r-- | tests/data/config.valid | 4 |
12 files changed, 72 insertions, 80 deletions
diff --git a/interface-definitions/https.xml.in b/interface-definitions/https.xml.in index 1d986b2b4..49bd25b82 100644 --- a/interface-definitions/https.xml.in +++ b/interface-definitions/https.xml.in @@ -111,6 +111,12 @@ <hidden/> </properties> </leafNode> + <leafNode name="virtual-host"> + <properties> + <help>Restrict proxy to virtual host(s)</help> + <multi/> + </properties> + </leafNode> </children> </node> <node name="certificates"> diff --git a/python/vyos/configdict.py b/python/vyos/configdict.py index 66da52ff3..24fe174d2 100644 --- a/python/vyos/configdict.py +++ b/python/vyos/configdict.py @@ -123,6 +123,7 @@ def vlan_to_dict(conf): 'ip_enable_arp_accept': 0, 'ip_enable_arp_announce': 0, 'ip_enable_arp_ignore': 0, + 'ip_proxy_arp': 0, 'ipv6_autoconf': 0, 'ipv6_forwarding': 1, 'ipv6_dup_addr_detect': 1, @@ -190,6 +191,10 @@ def vlan_to_dict(conf): if conf.exists('ip enable-arp-ignore'): vlan['ip_enable_arp_ignore'] = 1 + # Enable Proxy ARP + if conf.exists('ip enable-proxy-arp'): + vlan['ip_proxy_arp'] = 1 + # Enable acquisition of IPv6 address using stateless autoconfig (SLAAC) if conf.exists('ipv6 address autoconf'): vlan['ipv6_autoconf'] = 1 diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py index 0274f3573..a0b0eb3c1 100644 --- a/python/vyos/configtree.py +++ b/python/vyos/configtree.py @@ -24,58 +24,10 @@ def escape_backslash(string: str) -> str: result = p.sub(r'\\\\', string) return result -def strip_comments(s): - """ Split a config string into the config section and the trailing comments """ - INITIAL = 0 - IN_COMMENT = 1 - - i = len(s) - 1 - - state = INITIAL - - config_end = 0 - - # Find the first character of the comments section at the end, - # if it exists - while (i >= 0): - c = s[i] - - if (state == INITIAL) and re.match(r'\s', c): - # Ignore whitespace - if (i != 0): - i -= 1 - else: - config_end = 0 - break - elif (state == INITIAL) and not re.match(r'(\s|\/)', c): - # Assume there are no (more) trailing comments, - # this is an end of a node: either a brace of the last character - # of a leaf node value - config_end = i + 1 - break - elif (state == INITIAL) and (c == '/'): - # A comment begins, or it's a stray slash - if (s[i-1] == '*'): - state = IN_COMMENT - i -= 2 - else: - raise ValueError("Invalid syntax: stray slash at character {0}".format(i + 1)) - elif (state == IN_COMMENT) and (c == '*'): - # A comment ends here - try: - if (s[i-1] == '/'): - state = INITIAL - i -= 2 - except: - raise ValueError("Invalid syntax: malformed commend end at character {0}".format(i + 1)) - elif (state == IN_COMMENT) and (c != '*'): - # Ignore everything inside comments, including braces - i -= 1 - else: - # Shouldn't happen - raise ValueError("Invalid syntax at character {0}: invalid character {1}".format(i + 1, c)) - - return (s[0:config_end], s[config_end+1:]) +def extract_version(s): + """ Extract the version string from the config string """ + t = re.split('(^//)', s, maxsplit=1, flags=re.MULTILINE) + return (s, ''.join(t[1:])) def check_path(path): # Necessary type checking @@ -174,7 +126,7 @@ class ConfigTree(object): self.__destroy = self.__lib.destroy self.__destroy.argtypes = [c_void_p] - config_section, comments_section = strip_comments(config_string) + config_section, version_section = extract_version(config_string) config_section = escape_backslash(config_section) config = self.__from_string(config_section.encode()) if config is None: @@ -182,7 +134,7 @@ class ConfigTree(object): raise ValueError("Failed to parse config: {0}".format(msg)) else: self.__config = config - self.__comments = comments_section + self.__version = version_section def __del__(self): if self.__config is not None: @@ -193,7 +145,7 @@ class ConfigTree(object): def to_string(self): config_string = self.__to_string(self.__config).decode() - config_string = "{0}\n{1}".format(config_string, self.__comments) + config_string = "{0}\n{1}".format(config_string, self.__version) return config_string def to_commands(self): diff --git a/python/vyos/ifconfig/wireless.py b/python/vyos/ifconfig/wireless.py index 932d07d01..946ae1642 100644 --- a/python/vyos/ifconfig/wireless.py +++ b/python/vyos/ifconfig/wireless.py @@ -47,7 +47,7 @@ class WiFiIf(Interface): self._cmd(cmd) # wireless interface is administratively down by default - self.set_state('down') + self.set_admin_state('down') def _delete(self): cmd = 'iw dev {ifname} del' \ diff --git a/python/vyos/ifconfig_vlan.py b/python/vyos/ifconfig_vlan.py index 00270cf58..ed22646c1 100644 --- a/python/vyos/ifconfig_vlan.py +++ b/python/vyos/ifconfig_vlan.py @@ -64,6 +64,8 @@ def apply_vlan_config(vlan, config): vlan.set_arp_announce(config['ip_enable_arp_announce']) # configure ARP ignore vlan.set_arp_ignore(config['ip_enable_arp_ignore']) + # configure Proxy ARP + vlan.set_proxy_arp(config['ip_proxy_arp']) # IPv6 address autoconfiguration vlan.set_ipv6_autoconf(config['ipv6_autoconf']) # IPv6 forwarding diff --git a/python/vyos/migrator.py b/python/vyos/migrator.py index f05228041..9a5fdef2f 100644 --- a/python/vyos/migrator.py +++ b/python/vyos/migrator.py @@ -25,7 +25,7 @@ class MigratorError(Exception): pass class Migrator(object): - def __init__(self, config_file, force=False, set_vintage=None): + def __init__(self, config_file, force=False, set_vintage='vyos'): self._config_file = config_file self._force = force self._set_vintage = set_vintage @@ -61,9 +61,6 @@ class Migrator(object): if self._set_vintage: self._config_file_vintage = self._set_vintage - if not self._config_file_vintage: - self._config_file_vintage = vyos.defaults.cfg_vintage - if self._config_file_vintage not in ['vyatta', 'vyos']: raise MigratorError("Unknown vintage.") @@ -204,16 +201,12 @@ class Migrator(object): return self._changed class VirtualMigrator(Migrator): - def __init__(self, config_file, vintage='vyos'): - super().__init__(config_file, set_vintage = vintage) - def run(self): cfg_file = self._config_file cfg_versions = self.read_config_file_versions() if not cfg_versions: - raise MigratorError("Config file has no version information;" - " virtual migration not possible.") + return if self.update_vintage(): self._changed = True diff --git a/src/conf_mode/https.py b/src/conf_mode/https.py index a0fe9cf2f..889b62cf4 100755 --- a/src/conf_mode/https.py +++ b/src/conf_mode/https.py @@ -96,6 +96,7 @@ server { """ default_server_block = { + 'id' : '', 'address' : '*', 'port' : '443', 'name' : ['_'], @@ -117,6 +118,7 @@ def get_config(): else: for vhost in conf.list_nodes('virtual-host'): server_block = deepcopy(default_server_block) + server_block['id'] = vhost if conf.exists(f'virtual-host {vhost} listen-address'): addr = conf.return_value(f'virtual-host {vhost} listen-address') server_block['address'] = addr @@ -156,9 +158,21 @@ def get_config(): if conf.exists('api port'): port = conf.return_value('api port') api_data['port'] = port + if conf.exists('api virtual-host'): + vhosts = conf.return_values('api virtual-host') + api_data['vhost'] = vhosts[:] + if api_data: - for block in server_block_list: - block['api'] = api_data + # we do not want to include 'vhost' key as part of + # vyos.defaults.api_data, so check for key existence + vhost_list = api_data.get('vhost') + if vhost_list is None: + for block in server_block_list: + block['api'] = api_data + else: + for block in server_block_list: + if block['id'] in vhost_list: + block['api'] = api_data https = {'server_block_list' : server_block_list, 'certbot': certbot} return https diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py index 82a80d247..b6e62b0aa 100755 --- a/src/conf_mode/interfaces-wireless.py +++ b/src/conf_mode/interfaces-wireless.py @@ -1398,7 +1398,10 @@ def generate(wifi): # http://wiki.stocksy.co.uk/wiki/Multiple_SSIDs_with_hostapd # generate locally administered MAC address from used phy interface with open('/sys/class/ieee80211/{}/addresses'.format(wifi['phy']), 'r') as f: - tmp = EUI(f.read().rstrip()).value + # some PHYs tend to have multiple interfaces and thus supply multiple MAC + # addresses - we only need the first one for our calculation + tmp = f.readline().rstrip() + tmp = EUI(tmp).value # mask last nibble from the MAC address tmp &= 0xfffffffffff0 # set locally administered bit in MAC address diff --git a/src/helpers/run-config-migration.py b/src/helpers/run-config-migration.py index a57a19cdf..3c06e38f8 100755 --- a/src/helpers/run-config-migration.py +++ b/src/helpers/run-config-migration.py @@ -69,15 +69,22 @@ def main(): sys.exit(1) if not virtual: - migration = Migrator(config_file_name, force=force_on, - set_vintage=vintage) + virtual_migration = VirtualMigrator(config_file_name) + virtual_migration.run() + + migration = Migrator(config_file_name, force=force_on) + migration.run() + + if not migration.config_changed(): + os.remove(backup_file_name) else: - migration = VirtualMigrator(config_file_name) + virtual_migration = VirtualMigrator(config_file_name, + set_vintage=vintage) - migration.run() + virtual_migration.run() - if not migration._changed: - os.remove(backup_file_name) + if not virtual_migration.config_changed(): + os.remove(backup_file_name) if __name__ == '__main__': main() diff --git a/src/helpers/vyos-load-config.py b/src/helpers/vyos-load-config.py index 4e6d67efa..693529c23 100755 --- a/src/helpers/vyos-load-config.py +++ b/src/helpers/vyos-load-config.py @@ -28,7 +28,7 @@ import tempfile import vyos.defaults import vyos.remote from vyos.config import Config, VyOSError -from vyos.migrator import Migrator, MigratorError +from vyos.migrator import Migrator, VirtualMigrator, MigratorError system_config_file = 'config.boot' @@ -73,6 +73,12 @@ with tempfile.NamedTemporaryFile() as fp: with open(fp.name, 'w') as fd: fd.write(config_file) + virtual_migration = VirtualMigrator(fp.name) + try: + virtual_migration.run() + except MigratorError as err: + sys.exit('{}'.format(err)) + migration = Migrator(fp.name) try: migration.run() diff --git a/src/helpers/vyos-merge-config.py b/src/helpers/vyos-merge-config.py index c5216daa6..10a5ea4bc 100755 --- a/src/helpers/vyos-merge-config.py +++ b/src/helpers/vyos-merge-config.py @@ -21,9 +21,9 @@ import subprocess import tempfile import vyos.defaults import vyos.remote -import vyos.migrator from vyos.config import Config from vyos.configtree import ConfigTree +from vyos.migrator import Migrator, VirtualMigrator if (len(sys.argv) < 2): @@ -61,9 +61,13 @@ with tempfile.NamedTemporaryFile() as file_to_migrate: with open(file_to_migrate.name, 'w') as fd: fd.write(config_file) - migration = vyos.migrator.Migrator(file_to_migrate.name) + virtual_migration = VirtualMigrator(file_to_migrate.name) + virtual_migration.run() + + migration = Migrator(file_to_migrate.name) migration.run() - if migration.config_changed(): + + if virtual_migration.config_changed() or migration.config_changed(): with open(file_to_migrate.name, 'r') as fd: config_file = fd.read() diff --git a/tests/data/config.valid b/tests/data/config.valid index a21c6a4d1..1fbdd1505 100644 --- a/tests/data/config.valid +++ b/tests/data/config.valid @@ -35,5 +35,5 @@ empty-node { trailing-leaf-node-without-value -/* Trailing commend */ -/* Another trailing comment */ +// Trailing comment +// Another trailing comment |