Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-nmcli for openSUSE:Factory checked in at 2025-05-05 22:29:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-nmcli (Old) and /work/SRC/openSUSE:Factory/.python-nmcli.new.30101 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-nmcli" Mon May 5 22:29:37 2025 rev:2 rq:1274586 version:1.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-nmcli/python-nmcli.changes 2025-03-17 22:20:50.546622839 +0100 +++ /work/SRC/openSUSE:Factory/.python-nmcli.new.30101/python-nmcli.changes 2025-05-05 22:59:29.648284800 +0200 @@ -1,0 +2,10 @@ +Mon May 5 12:06:51 UTC 2025 - Felix Stegmeier <felix.stegme...@suse.com> + +- Update to 1.5.0 + * Added show_secrets option to nmcli.connection.show + +- Update to 1.4.0 + * Supported unsupported cases of DeviceWifi.parse. + * Fixed the problem that nmcli.general does not work on nmcli client after version 1.48.x. + +------------------------------------------------------------------- Old: ---- nmcli-1.3.0.tar.gz New: ---- nmcli-1.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-nmcli.spec ++++++ --- /var/tmp/diff_new_pack.IRKmxm/_old 2025-05-05 22:59:30.196307842 +0200 +++ /var/tmp/diff_new_pack.IRKmxm/_new 2025-05-05 22:59:30.200308010 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-nmcli # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,18 +17,18 @@ Name: python-nmcli -Version: 1.3.0 +Version: 1.5.0 Release: 0 Summary: A python wrapper library for the network-manager cli client License: MIT URL: https://github.com/ushiboy/nmcli Source: https://github.com/ushiboy/nmcli/archive/refs/tags/v%{version}.tar.gz#/nmcli-%{version}.tar.gz -BuildRequires: python-rpm-macros BuildRequires: %{python_module pip} +BuildRequires: %{python_module pytest} BuildRequires: %{python_module setuptools} BuildRequires: %{python_module wheel} -BuildRequires: %{python_module pytest} BuildRequires: fdupes +BuildRequires: python-rpm-macros BuildArch: noarch Requires: NetworkManager ++++++ nmcli-1.3.0.tar.gz -> nmcli-1.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/.github/workflows/action.yml new/nmcli-1.5.0/.github/workflows/action.yml --- old/nmcli-1.3.0/.github/workflows/action.yml 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/.github/workflows/action.yml 2024-12-07 07:28:49.000000000 +0100 @@ -1,6 +1,10 @@ name: develop action -on: [push] +on: + push: + branches: [main] + pull_request: + workflow_dispatch: jobs: build: @@ -9,8 +13,8 @@ matrix: python-version: ['3.7', '3.8', '3.9', '3.10'] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/README.md new/nmcli-1.5.0/README.md --- old/nmcli-1.3.0/README.md 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/README.md 2024-12-07 07:28:49.000000000 +0100 @@ -1,5 +1,4 @@ -nmcli -===== +# nmcli nmcli is a python wrapper library for the network-manager cli client. @@ -31,62 +30,61 @@ ## Dependency -* NetworkManager - * `sudo apt install network-manager` (Debian) -* User who can execute nmcli with sudo with NOPASSWD - * If sudo is not needed (like root user), use `disable_use_sudo` at the beginning of the process. +- NetworkManager + - `sudo apt install network-manager` (Debian) +- User who can execute nmcli with sudo with NOPASSWD + - If sudo is not needed (like root user), use `disable_use_sudo` at the beginning of the process. ## Compatibility table -| Object | Command | Status | -|--------|---------|--------| -| general | | supported | -| general | status | supported | -| general | hostname | supported | -| general | permissions | not supported | -| general | logging | not supported | -| networking | | supported | -| networking | on | supported | -| networking | off | supported | -| networking | connectivity | supported | -| radio | | supported | -| radio | all | supported | -| radio | wifi | supported | -| radio | wwan | supported | -| connection | | supported | -| connection | show | supported | -| connection | up | supported | -| connection | down | supported | -| connection | add | supported | -| connection | modify | supported | -| connection | clone | not supported | -| connection | edit | not supported | -| connection | delete | supported | -| connection | reload | supported | -| connection | load | not supported | -| connection | import | not supported | -| connection | export | not supported | -| device | | supported | -| device | status | supported | -| device | show | supported | -| device | set | not supported | -| device | connect | supported | -| device | reapply | supported | -| device | modify | not supported | -| device | disconnect | supported | -| device | delete | supported | -| device | monitor | not supported | -| device | wifi | supported | -| device | wifi connect | supported | -| device | wifi rescan | supported | -| device | wifi hotspot | supported | -| device | lldp | not supported | -| agent | | not supported | -| agent | secret | not supported | -| agent | polkit | not supported | -| agent | all | not supported | -| monitor | | not supported | - +| Object | Command | Status | +| ---------- | ------------ | ------------- | +| general | | supported | +| general | status | supported | +| general | hostname | supported | +| general | permissions | not supported | +| general | logging | not supported | +| networking | | supported | +| networking | on | supported | +| networking | off | supported | +| networking | connectivity | supported | +| radio | | supported | +| radio | all | supported | +| radio | wifi | supported | +| radio | wwan | supported | +| connection | | supported | +| connection | show | supported | +| connection | up | supported | +| connection | down | supported | +| connection | add | supported | +| connection | modify | supported | +| connection | clone | not supported | +| connection | edit | not supported | +| connection | delete | supported | +| connection | reload | supported | +| connection | load | not supported | +| connection | import | not supported | +| connection | export | not supported | +| device | | supported | +| device | status | supported | +| device | show | supported | +| device | set | not supported | +| device | connect | supported | +| device | reapply | supported | +| device | modify | not supported | +| device | disconnect | supported | +| device | delete | supported | +| device | monitor | not supported | +| device | wifi | supported | +| device | wifi connect | supported | +| device | wifi rescan | supported | +| device | wifi hotspot | supported | +| device | lldp | not supported | +| agent | | not supported | +| agent | secret | not supported | +| agent | polkit | not supported | +| agent | all | not supported | +| monitor | | not supported | ## API @@ -155,8 +153,10 @@ Show details for specified connections. +Use `show_secrets` argument to reveal associated secrets as well. + ``` -nmcli.connection.show(name: str) -> ConnectionDetails +nmcli.connection.show(name: str, show_secrets: bool = False) -> ConnectionDetails ``` #### nmcli.connection.reload @@ -239,7 +239,6 @@ The `wait` argument applies the same effect to the command as the `--wait` option. If it is omitted, the default behavior is followed. - ``` nmcli.device.delete(ifname: str, wait: int = None) -> None ``` @@ -459,6 +458,15 @@ ## Change Log +### 1.5.0 + +- Added show_secrets option to `nmcli.connection.show` + +### 1.4.0 + +- Supported unsupported cases of `DeviceWifi.parse`. +- Fixed the problem that `nmcli.general` does not work on nmcli client after version 1.48.x. + ### 1.3.0 - Added rescan parameter to `nmcli.device.wifi`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/nmcli/_connection.py new/nmcli-1.5.0/nmcli/_connection.py --- old/nmcli-1.3.0/nmcli/_connection.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/nmcli/_connection.py 2024-12-07 07:28:49.000000000 +0100 @@ -31,7 +31,7 @@ def down(self, name: str, wait: int = None) -> None: raise NotImplementedError - def show(self, name: str) -> ConnectionDetails: + def show(self, name: str, show_secrets: bool = False) -> ConnectionDetails: raise NotImplementedError def reload(self) -> None: @@ -88,8 +88,11 @@ wait) + ['connection', 'down', name] self._syscmd.nmcli(cmd) - def show(self, name: str) -> ConnectionDetails: - r = self._syscmd.nmcli(['connection', 'show', name]) + def show(self, name: str, show_secrets: bool = False) -> ConnectionDetails: + cmd = ['connection', 'show', name] + if show_secrets: + cmd += ["--show-secrets"] + r = self._syscmd.nmcli(cmd) results = {} for row in r.split('\n'): m = re.search(r'^(\S+):\s*([\S\s]+)\s*', row) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/nmcli/data/device.py new/nmcli-1.5.0/nmcli/data/device.py --- old/nmcli-1.3.0/nmcli/data/device.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/nmcli/data/device.py 2024-12-07 07:28:49.000000000 +0100 @@ -64,7 +64,7 @@ t = text.replace("\\:", "\uFFFE").replace( ":", "\uFFFF").replace("\uFFFE", ":") m = re.search( - r'^(\*|\s)\uFFFF(.*)\uFFFF(.*)\uFFFF(.*)\uFFFF(\d+)\uFFFF(\d+)\sMHz\uFFFF(\d+)\sMbit\/s\uFFFF(\d+)\uFFFF(.*)$', t) + r'^(\*|\s)\uFFFF(.*)\uFFFF(.*)\uFFFF(.*)\uFFFF(\d+)\uFFFF(\d+)\sMHz\uFFFF(\d+)\s(?:Mb|Mbit)\/s\uFFFF(\d+)\uFFFF(.*)$', t) if m: in_use, ssid, bssid, mode, chan, freq, rate, signal, security = m.groups() return DeviceWifi(in_use == '*', ssid, bssid, mode, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/nmcli/data/general.py new/nmcli-1.5.0/nmcli/data/general.py --- old/nmcli-1.3.0/nmcli/data/general.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/nmcli/data/general.py 2024-12-07 07:28:49.000000000 +0100 @@ -25,12 +25,43 @@ 'wwan': self.wwan } +# case 1: +# STATE CONNECTIVITY WIFI-HW WIFI WWAN-HW WWAN METERED +# connected full enabled enabled missing enabled no (guessed) +# +# case 2: +# unknown none enabled enabled enabled disabled +# +# case 3: +# connected (local only) full disabled enabled enabled enabled +# +# see: https://regex101.com/r/zW1hHE/1 + @classmethod def parse(cls, text: str) -> General: - m = re.search( - r'^([\S\s]+)\s{2}(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*', text) + pattern = ( + r'^' + + r'(?P<state>.+)' + + r' ' + + r'(?P<connectivity>\S+)' + + r'\s+' + + r'(?P<wifi_hw>\S+)' + + r' ' + + r'(?P<wifi>\S+)' + + r' ' + + r'(?P<wwan_hw>\S+)' + + r' ' + + r'(?P<wwan>\S+)' + + r'(?: (?P<metered>.+)?)?' + + r'$' + ) + + # The execution result will have a trailing space, + # so trim it and then match it to the pattern. + m = re.search(pattern, text.rstrip()) + if m: - state, connectivity, wifi_hw, wifi, wwan_hw, wwan = m.groups() + state, connectivity, wifi_hw, wifi, wwan_hw, wwan, _metered = m.groups() return General(NetworkManagerState(state), NetworkConnectivity(connectivity), wifi_hw == 'enabled', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/nmcli/dummy/_connection.py new/nmcli-1.5.0/nmcli/dummy/_connection.py --- old/nmcli-1.3.0/nmcli/dummy/_connection.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/nmcli/dummy/_connection.py 2024-12-07 07:28:49.000000000 +0100 @@ -28,6 +28,10 @@ return self._down_args @property + def show_args(self): + return self._show_args + + @property def called_reload(self) -> int: return self._called_reload @@ -43,6 +47,7 @@ self._delete_args: List[Tuple] = [] self._up_args: List[Tuple] = [] self._down_args: List[Tuple] = [] + self._show_args: List[Tuple] = [] self._called_reload = 0 def __call__(self) -> List[Connection]: @@ -74,8 +79,9 @@ self._raise_error_if_needed() self._down_args.append((name, wait)) - def show(self, name: str) -> ConnectionDetails: + def show(self, name: str, show_secrets: bool = False) -> ConnectionDetails: self._raise_error_if_needed() + self._show_args.append((name, show_secrets)) if not self._result_show is None: return self._result_show raise ValueError("'result_show' is not properly initialized") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/setup.py new/nmcli-1.5.0/setup.py --- old/nmcli-1.3.0/setup.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/setup.py 2024-12-07 07:28:49.000000000 +0100 @@ -13,7 +13,7 @@ setup( name='nmcli', - version='1.3.0', + version='1.5.0', author='ushiboy', license='MIT', license_files = ('LICENSE.txt',), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/tests/data/test_device.py new/nmcli-1.5.0/tests/data/test_device.py --- old/nmcli-1.3.0/tests/data/test_device.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/tests/data/test_device.py 2024-12-07 07:28:49.000000000 +0100 @@ -75,6 +75,10 @@ assert DeviceWifi.parse(d4) == \ DeviceWifi(False, 'AAAAAA BBBBBBBBB CCC 9999', '00:00:00:00:00:03', 'Infra', 1, 2403, 130, 82, 'WPA1 WPA2') + d5 = '*:AP1:00\\:00\\:00\\:00\\:00\\:00:Infra:1:2400 MHz:130 Mb/s:82:WPA1 WPA2' + assert DeviceWifi.parse(d5) == \ + DeviceWifi(True, 'AP1', '00:00:00:00:00:00', + 'Infra', 1, 2400, 130, 82, 'WPA1 WPA2') def test_device_wifi_parse_when_failed(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/tests/data/test_general.py new/nmcli-1.5.0/tests/data/test_general.py --- old/nmcli-1.3.0/tests/data/test_general.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/tests/data/test_general.py 2024-12-07 07:28:49.000000000 +0100 @@ -23,41 +23,46 @@ def test_parse(): - d1 = 'unknown none enabled enabled enabled disabled' + d1 = 'unknown none enabled enabled enabled disabled ' assert General.parse(d1) == General(NetworkManagerState.UNKNOWN, NetworkConnectivity.NONE, True, True, True, False) - d2 = 'asleep portal enabled enabled disabled enabled' + d2 = 'asleep portal enabled enabled disabled enabled ' assert General.parse(d2) == General(NetworkManagerState.ASLEEP, NetworkConnectivity.PORTAL, True, True, False, True) - d3 = 'connecting limited enabled disabled enabled enabled' + d3 = 'connecting limited enabled disabled enabled enabled ' assert General.parse(d3) == General(NetworkManagerState.CONNECTING, NetworkConnectivity.LIMITED, True, False, True, True) - d4 = 'connected (local only) full disabled enabled enabled enabled' + d4 = 'connected (local only) full disabled enabled enabled enabled ' assert General.parse(d4) == General(NetworkManagerState.CONNECTED_LOCAL, NetworkConnectivity.FULL, False, True, True, True) - d5 = 'connected (site only) full enabled enabled enabled enabled' + d5 = 'connected (site only) full enabled enabled enabled enabled ' assert General.parse(d5) == General(NetworkManagerState.CONNECTED_SITE, NetworkConnectivity.FULL, True, True, True, True) - d6 = 'disconnecting full enabled enabled enabled enabled' + d6 = 'disconnecting full enabled enabled enabled enabled ' assert General.parse(d6) == General(NetworkManagerState.DISCONNECTING, NetworkConnectivity.FULL, True, True, True, True) - d7 = 'disconnected full enabled enabled enabled enabled' + d7 = 'disconnected full enabled enabled enabled enabled ' assert General.parse(d7) == General(NetworkManagerState.DISCONNECTED, NetworkConnectivity.FULL, True, True, True, True) + d8 = 'connected full enabled enabled missing enabled no (guessed) ' + assert General.parse(d8) == General(NetworkManagerState.CONNECTED_GLOBAL, + NetworkConnectivity.FULL, + True, True, False, True) + def test_parse_when_failed(): with pytest.raises(ValueError) as e: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/tests/dummy/test_connection.py new/nmcli-1.5.0/tests/dummy/test_connection.py --- old/nmcli-1.3.0/tests/dummy/test_connection.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/tests/dummy/test_connection.py 2024-12-07 07:28:49.000000000 +0100 @@ -110,8 +110,13 @@ 'key': 'value' } c = DummyConnectionControl(result_show=result_show) + name = 'MyHome' assert c.show(name) == result_show + assert c.show_args[0] == (name, False) + + c.show(name, show_secrets=True) + assert c.show_args[1] == (name, True) def test_show_when_raise_error(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nmcli-1.3.0/tests/test_connection.py new/nmcli-1.5.0/tests/test_connection.py --- old/nmcli-1.3.0/tests/test_connection.py 2023-10-07 06:20:52.000000000 +0200 +++ new/nmcli-1.5.0/tests/test_connection.py 2024-12-07 07:28:49.000000000 +0100 @@ -112,7 +112,10 @@ buf = f.read() s = DummySystemCommand(buf) connection = ConnectionControl(s) - r = connection.show('Wired connection 1') + name = 'Wired connection 1' + + r = connection.show(name) + assert s.passed_parameters == ['connection', 'show', name] assert len(r.keys()) == 114 assert r['connection.id'] == 'Wired connection 1' assert r['connection.stable-id'] is None @@ -120,6 +123,10 @@ assert r['IP4.ADDRESS[1]'] == '192.168.1.10/24' assert r['DHCP6.OPTION[8]'] == 'requested_dhcp6_name_servers = 1' + connection.show(name, show_secrets=True) + assert s.passed_parameters == [ + 'connection', 'show', name, "--show-secrets"] + def test_reload(): s = DummySystemCommand()