diff options
author | Christian Breunig <christian@breunig.cc> | 2023-12-16 16:01:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-16 16:01:50 +0100 |
commit | 03202504d559417266e437bbf53eb26ade187c07 (patch) | |
tree | 3fdccb067cdda337cd04542ae9b609970521ede4 /src/migration-scripts/dns-dynamic/2-to-3 | |
parent | e8282aa4f7e675d1189864799940c9a1b097601c (diff) | |
parent | 2b96bc8532b61be96cea92cc1c5468bd5fc3d968 (diff) | |
download | vyos-1x-03202504d559417266e437bbf53eb26ade187c07.tar.gz vyos-1x-03202504d559417266e437bbf53eb26ade187c07.zip |
Merge pull request #2617 from indrajitr/ddclient-improvement-round-3-2023-12-11
ddclient: T5144,T5791: Fix migration to avoid config name conflict
Diffstat (limited to 'src/migration-scripts/dns-dynamic/2-to-3')
-rwxr-xr-x | src/migration-scripts/dns-dynamic/2-to-3 | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/src/migration-scripts/dns-dynamic/2-to-3 b/src/migration-scripts/dns-dynamic/2-to-3 index 187c2a895..e5910f7b4 100755 --- a/src/migration-scripts/dns-dynamic/2-to-3 +++ b/src/migration-scripts/dns-dynamic/2-to-3 @@ -21,10 +21,27 @@ # to "service dns dynamic name <service> address <interface> protocol 'nsupdate'" # - migrate "service dns dynamic address <interface> service <service> ..." # to "service dns dynamic name <service> address <interface> ..." +# - normalize the all service names to conform with name constraints import sys +import re +from unicodedata import normalize from vyos.configtree import ConfigTree +def normalize_name(name): + """Normalize service names to conform with name constraints. + + This is necessary as part of migration because there were no constraints in + the old name format. + """ + # Normalize unicode characters to ASCII (NFKD) + # Replace all separators with hypens, strip leading and trailing hyphens + name = normalize('NFKD', name).encode('ascii', 'ignore').decode() + name = re.sub(r'(\s|\W)+', '-', name).strip('-') + + return name + + if len(sys.argv) < 2: print("Must specify file name!") sys.exit(1) @@ -64,22 +81,36 @@ for address in config.list_nodes(address_path): for svc_type in ['service', 'rfc2136']: if config.exists(address_path_tag + [svc_type]): - # Move RFC2136 as service configuration, rename to avoid name conflict and set protocol to 'nsupdate' + # Set protocol to 'nsupdate' for RFC2136 configuration if svc_type == 'rfc2136': - for rfc_cfg_old in config.list_nodes(address_path_tag + ['rfc2136']): - rfc_cfg_new = f'{rfc_cfg_old}-rfc2136' - config.rename(address_path_tag + ['rfc2136', rfc_cfg_old], rfc_cfg_new) - config.set(address_path_tag + ['rfc2136', rfc_cfg_new, 'protocol'], 'nsupdate') + for rfc_cfg in config.list_nodes(address_path_tag + ['rfc2136']): + config.set(address_path_tag + ['rfc2136', rfc_cfg, 'protocol'], 'nsupdate') # Add address as config value in each service before moving the service path - # And then copy the services from 'address <interface> service <service>' to 'name <service>' + # And then copy the services from 'address <interface> service <service>' + # to 'name (service|rfc2136)-<service>-<address>' + # Note: The new service is named (service|rfc2136)-<service>-<address> + # to avoid name conflict with old entries for svc_cfg in config.list_nodes(address_path_tag + [svc_type]): config.set(address_path_tag + [svc_type, svc_cfg, 'address'], address) - config.copy(address_path_tag + [svc_type, svc_cfg], name_path + [svc_cfg]) + config.copy(address_path_tag + [svc_type, svc_cfg], + name_path + ['-'.join([svc_type, svc_cfg, address])]) # Finally cleanup the old address path config.delete(address_path) +# Normalize the all service names to conform with name constraints +index = 1 +for name in config.list_nodes(name_path): + new_name = normalize_name(name) + if new_name != name: + # Append index if there is still a name conflicts after normalization + # For example, "foo-?(" and "foo-!)" both normalize to "foo-" + if config.exists(name_path + [new_name]): + new_name = f'{new_name}-{index}' + index += 1 + config.rename(name_path + [name], new_name) + try: with open(file_name, 'w') as f: f.write(config.to_string()) |