PythonでNetworkManagerを操作する 【python-networkmanager】


PythonからNetworkManagerを操作し、Linuxのネットワーク設定を行えるようにします。
python-networkmanagerというライブラリを使用します。
このライブラリは特徴は、裏でnmcli等のツールを呼び出してパースしているのではなく、
D-busというものでNetworkManagerと直接やり取りしているところです。
残念ながらドキュメントがしっかりしていないので、自分用の備忘録を兼ねて書いていきます。

なお、こちらではRockyLinux8.5を使用しています。

準備

python-networkmanagerをインストールします。

インストール
$ pip3 install python-networkmanager

念のためNetworkManagerが動作しているか確認します。

NetworkManager
$ systemctl status NetworkManager
● NetworkManager.service - Network Manager
   Loaded: loaded (/usr/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2022-03-26 22:51:21 JST; 1h 36min ago
~~

ライブラリの動作確認をします。

動作確認
from dbus.mainloop.glib import DBusGMainLoop
import NetworkManager

DBusGMainLoop(set_as_default=True)

print(NetworkManager.NetworkManager.Version)

実行して1.32.10などとNetworkManagerのバージョンが表示されていれば成功です。
注意点として必ずNetworkManagerのライブラリを呼び出す前に
DBusGMainLoop(set_as_default=True)
を実行しないとエラーになってしまうようです。

デバイス情報

NetworkManagerからデバイス一覧を取得します。

現在、以下の状態になっています。

device
$ nmcli dev
DEVICE    TYPE      STATE     CONNECTION
ens18     ethernet  接続済み  ens18
ens19     ethernet  接続済み  eth1
ens19.20  vlan      接続済み  eth1.20
lo        loopback  管理無し  --

以下のプログラムを実行すると

device.py
from dbus.mainloop.glib import DBusGMainLoop
import NetworkManager

DBusGMainLoop(set_as_default=True)

devices = NetworkManager.NetworkManager.GetDevices()

for dev in devices:
    print('device :', dev.Interface)
    print('state :', NetworkManager.const('device_state', dev.State))
    print('type :', NetworkManager.const('device_type', dev.DeviceType))

    for addr in dev.Ip4Config.Addresses:
        print('addr : {}/{}'.format(addr[0], addr[1]))
    print('------------------')

このような結果になります。

device.py 実行結果
$ python3 device.py
device : lo
state : unmanaged
type : generic
addr : 127.0.0.1/8
------------------
device : ens18
state : activated
type : ethernet
addr : 192.168.50.100/24
------------------
device : ens19
state : activated
type : ethernet
addr : 172.16.10.106/24
------------------
device : ens19.20
state : activated
type : vlan
addr : 172.16.20.70/24
------------------

ポイントを解説します。
NetworkManager.NetworkManager.GetDevices()でデバイスの一覧をList型で取得できます。
オブジェクトのプロパティから各種情報を参照できます。
NetworkManager.const()で定数値を名前に変換することができます。

参考文献

https://pythonhosted.org/python-networkmanager/
https://github.com/seveas/python-networkmanager