Bug 55391 - umc-command ip/change works only for IPv4 and removes an IPv6 address from current host/server
umc-command ip/change works only for IPv4 and removes an IPv6 address from cu...
Status: NEW
Product: UCS
Classification: Unclassified
Component: DNS
UCS 5.0
Other Linux
: P5 normal (vote)
: ---
Assigned To: UCS maintainers
UCS maintainers
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2022-11-06 20:18 CET by Gino Harlos
Modified: 2023-02-27 10:31 CET (History)
2 users (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 3: Simply Wrong: The implementation doesn't match the docu
Who will be affected by this bug?: 1: Will affect a very few installed domains
How will those affected feel about the bug?: 3: A User would likely not purchase the product
User Pain: 0.051
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional): bitesize, External feedback
Max CVSS v3 score:
best: Patch_Available+


Attachments
Patch suggestion (7.67 KB, patch)
2022-11-06 20:18 CET, Gino Harlos
Details | Diff
Patch suggestion for univention internal tests (3.79 KB, patch)
2022-11-06 20:19 CET, Gino Harlos
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Gino Harlos 2022-11-06 20:18:15 CET
Created attachment 11007 [details]
Patch suggestion

If the IP changed, maybe for a container, umc-command ip/change will only work for IPv4 and loses any old IP addresses.

Let change the ip address(es) for container ... ( docker or podman, that does not matter )

[root@podman ~]# podman stop pdc.ucs.example && podman network disconnect ucs pdc.ucs.example && podman network connect --ip 172.26.0.2 --ip6 fdff:172:26:0::2 ucs pdc.ucs.example
[root@podman ~]# podman start pdc.ucs.example
...
root@pdc:~# umc-command --username $(ucr get hostname)\$ --password $(</etc/machine.secret) ip/change --option ip=fdff:172:26:0::2 --option netmask=64 --option role=$(ucr get server/role)
...
ipaddress.AddressValueError: Expected 4 octets in fdff:172:26:0::2
...

Environment:
 - inside /usr/sbin/umc-command ip/change ( with or without samba as backend )
 - systemd-detect-virt => docker and/or kvm ( not tested on a real machine! )
 - reproduce command for a SHELL/BASH as root user ( inside container or kvm )

Reproduce ORIGINAL:
root@pdc:~# umc-command --username $(ucr get hostname)\$ --password $(</etc/machine.secret) ip/change --option ip=::1 --option netmask=128 --option role=$(ucr get server/role)
Response: COMMAND
  data length   :   82
  message length: 1807
  ---
  ARGUMENTS: ip/change
MIMETYPE   : application/json
  STATUS   : 591
  MESSAGE  : Internal server error during "ip/change".
  ERROR    : {'command': 'ip/change', 'traceback': 'Traceback ...'}
  RESULT   : {'result': None, 'message': 'Internal server error during "ip/change".', 'headers': {'Vary': 'Content-Language', 'Content-Language': 'en-US'}, 'error': {'command': 'ip/change', 'traceback': 'Traceback (most recent call last):\n  File "/usr/lib/python3/dist-packages/univention/management/console/base.py", line 347, in __error_handling\n    six.reraise(etype, exc, etraceback)\n  File "/usr/lib/python3/dist-packages/six.py", line 693, in reraise\n    raise value\n  File "/usr/lib/python3/dist-packages/univention/management/console/base.py", line 250, in execute\n    function.__func__(self, request, *args, **kwargs)\n  File "/usr/lib/python3/dist-packages/univention/management/console/modules/decorators.py", line 324, in _response\n    result = _multi_response(self, request)\n  File "/usr/lib/python3/dist-packages/univention/management/console/modules/decorators.py", line 184, in _response\n    return function(self, request)\n  File "/usr/lib/python3/dist-packages/univention/management/console/modules/decorators.py", line 446, in _response\n    return list(function(self, iterator, *nones))\n  File "/usr/lib/python3/dist-packages/univention/management/console/modules/decorators.py", line 292, in _fake_func\n    yield function(self, *args)\n  File "/usr/lib/python3/dist-packages/univention/management/console/modules/ipchange/__init__.py", line 63, in change\n    network = ipaddress.IPv4Network(f\'{ip}/{netmask}\', False)\n  File "/usr/lib/python3.7/ipaddress.py", line 1528, in __init__\n    addr = self._ip_int_from_string(args[0])\n  File "/usr/lib/python3.7/ipaddress.py", line 1135, in _ip_int_from_string\n    raise AddressValueError("Expected 4 octets in %r" % ip_str)\nipaddress.AddressValueError: Expected 4 octets in \'::1\'\n'}, 'reason': None, 'status': 591}
... Traceback ( /usr/lib/python3/dist-packages/univention/management/console/modules/ipchange/__init__.py ) ...
... network = ipaddress.IPv4Network(f'{ip}/{netmask}', False) ...

ipaddress.AddressValueError: Expected 4 octets in ::1

Reproduce PATCHED:
root@pdc:~# umc-command --username $(ucr get hostname)\$ --password $(</etc/machine.secret) ip/change --option ip=::1 --option netmask=128 --option role=$(ucr get server/role)
Response: COMMAND
  data length   :   82
  message length:  149
  ---
  ARGUMENTS: ip/change
MIMETYPE   : application/json
  STATUS   : 200
  MESSAGE  : None
  RESULT   : {'result': None, 'message': None, 'headers': {'Vary': 'Content-Language', 'Content-Language': 'en-US'}, 'error': None, 'reason': None, 'status': 200}
... /var/log/univention/management-console-module-ipchange.log ...

MODULE      ( ERROR   ) : Ignore link local or loopback address change.

Patch suggestion:
...
--- a/management/univention-management-console-module-ipchange/umc/python/ipchange/__init__.py
+++ b/management/univention-management-console-module-ipchange/umc/python/ipchange/__init__.py
...
-               network = ipaddress.IPv4Network(f'{ip}/{netmask}', False)
+               network = ipaddress.ip_network(f'{ip}/{netmask}', False)
... will support IPv4 and IPv6

Some facts about the patch suggestion:
...
--- a/management/univention-management-console-module-ipchange/umc/python/ipchange/__init__.py
+++ b/management/univention-management-console-module-ipchange/umc/python/ipchange/__init__.py
...
-               if network.is_link_local:
+               if network.is_link_local or network.is_loopback:
... a loopback address as host record or server address doesn't make sense

...
+               saddresses = [entry for entry in server.get('ip') if ipaddress.ip_address(entry).version == network.version]
... read the current server status filtert by address version

...
+               # set attribute aRecord(<split>.|<trim>0) or aAAARecord(<split>:|<trim>0000) for IP version 4 or 6
+               if network.version == 4:
+                       attribute = 'aRecord';    sattribute = '.'; tattribute = '0'
+               if network.version == 6:
+                       attribute = 'aAAARecord'; sattribute = ':'; tattribute = '0000'
... will switch between the address versions ( IPv4/IPv6 )

...
-               server['ip'] = ip
+               server['ip'].append(naddress)
... will not remove the opposite version of the IP address ( this will support one IPv4 and one IPv6 address )

...
+                       naddress = ipaddress.ip_address(ip).exploded
+                       oaddress = ipaddress.ip_address(oldip).exploded
... always search with exploded address version too ( aAAARecords )

Patch suggestion: ( for univention internal tests )
 - I don't know if your internal tests running in IPv6 too. So it will be ignord ... if ucr.get('interfaces/%s/ipv6/default/prefix' % iface) ... not presend.

Patch evaluations:
root@pdc:~# for dns in ptr_record host_record reverse_zone forward_zone; do udm dns/${dns} list; done
...
 - append/remove pTRRecords looks nice ( old records will be removed automaticly )
 - append/remove aRecords and aAAARecords fixed for host records including samba and forward zones
 - append/remove ip(s) for computer/{role} fixed ( append/remove vs. overwrite )
 - append/remove ... --option oldip ... is now more an atitional cleanup and no longer requried, but nice to have

Patch beneficiary:
 - https://forge.univention.org/bugzilla/show_bug.cgi?id=54189 ( oldip no longer needed )
 - https://forge.univention.org/bugzilla/show_bug.cgi?id=53252 ( UCS AD[gc._msdcs, DomainDnsZones, ForestDnsZones] change the relevant host records too )
 - https://forge.univention.org/bugzilla/show_bug.cgi?id=39913 ( oldip no longer needed )
Comment 1 Gino Harlos 2022-11-06 20:19:09 CET
Created attachment 11008 [details]
Patch suggestion for univention internal tests

Patch suggestion: ( for univention internal tests )
 - I don't know if your internal tests running in IPv6 too. So it will be ignord ... if ucr.get('interfaces/%s/ipv6/default/prefix' % iface) ... not presend.