Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fetch DHCP leases from nmcli over dbus #418

Open
glimchb opened this issue Jun 24, 2024 · 8 comments · May be fixed by #427
Open

fetch DHCP leases from nmcli over dbus #418

glimchb opened this issue Jun 24, 2024 · 8 comments · May be fixed by #427
Assignees
Labels
good first issue Good for newcomers

Comments

@glimchb
Copy link
Member

glimchb commented Jun 24, 2024

See xPU sZTP provisioning block

today we pass lease file via cmdline arguments like this: --dhcp-lease-file /var/lib/dhclient/dhclient.leases.

but can we detect that info automatically from Network Manager over dbus ?

spec https://networkmanager.dev/

for example I found:

root@bf2:~# nmcli -f DHCP4 device show oob_net0
DHCP4.OPTION[1]:                        broadcast_address = 172.22.255.255
DHCP4.OPTION[2]:                        dad_wait_time = 0
DHCP4.OPTION[3]:                        dhcp_lease_time = 600
DHCP4.OPTION[4]:                        dhcp_message_type = 5
DHCP4.OPTION[5]:                        dhcp_server_identifier = 172.22.0.1
DHCP4.OPTION[6]:                        domain_name = lab.opiproject.org
DHCP4.OPTION[7]:                        domain_name_servers = 8.8.8.8 1.1.1.1
DHCP4.OPTION[8]:                        expiry = 1718831245
DHCP4.OPTION[9]:                        ip_address = 172.22.3.2
DHCP4.OPTION[10]:                       network_number = 172.22.0.0
DHCP4.OPTION[11]:                       next_server = 172.22.0.1
DHCP4.OPTION[12]:                       requested_broadcast_address = 1
DHCP4.OPTION[13]:                       requested_domain_name = 1
DHCP4.OPTION[14]:                       requested_domain_name_servers = 1
DHCP4.OPTION[15]:                       requested_domain_search = 1
DHCP4.OPTION[16]:                       requested_host_name = 1
DHCP4.OPTION[17]:                       requested_interface_mtu = 1
DHCP4.OPTION[18]:                       requested_ms_classless_static_routes = 1
DHCP4.OPTION[19]:                       requested_netbios_name_servers = 1
DHCP4.OPTION[20]:                       requested_netbios_scope = 1
DHCP4.OPTION[21]:                       requested_ntp_servers = 1
DHCP4.OPTION[22]:                       requested_rfc3442_classless_static_routes = 1
DHCP4.OPTION[23]:                       requested_root_path = 1
DHCP4.OPTION[24]:                       requested_routers = 1
DHCP4.OPTION[25]:                       requested_static_routes = 1
DHCP4.OPTION[26]:                       requested_subnet_mask = 1
DHCP4.OPTION[27]:                       requested_sztp_redirect_urls = 1
DHCP4.OPTION[28]:                       requested_time_offset = 1
DHCP4.OPTION[29]:                       requested_wpad = 1
DHCP4.OPTION[30]:                       routers = 172.22.0.1
DHCP4.OPTION[31]:                       subnet_mask = 255.255.0.0
DHCP4.OPTION[32]:                       sztp_redirect_urls = https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data

or using dbus directly:

root@bf2:~# busctl -j call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects | jq .[] |  grep -C 3 sztp
              "type": "s",
              "data": "1"
            },
            "requested_sztp_redirect_urls": {
              "type": "s",
              "data": "1"
            },
--
              "type": "s",
              "data": "255.255.0.0"
            },
            "sztp_redirect_urls": {
              "type": "s",
              "data": "https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data"
            }
          }
        }

Working example in python:

>>> import dbus
>>>
>>> bus = dbus.SystemBus()
>>> nm = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
>>> conn = bus.get_object("org.freedesktop.NetworkManager", nm.Get("org.freedesktop.NetworkManager", "PrimaryConnection", dbus_interface="org.freedesktop.DBus.Properties"))
>>> dhcp = bus.get_object("org.freedesktop.NetworkManager", conn.Get("org.freedesktop.NetworkManager.Connection.Active", "Dhcp4Config", dbus_interface="org.freedesktop.DBus.Properties"))
>>> options = dhcp.Get("org.freedesktop.NetworkManager.DHCP4Config", "Options", dbus_interface="org.freedesktop.DBus.Properties")
>>> print(str(options["sztp_redirect_urls"]))
https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data

Now need to find go bindings for it...

Maybe https://github.com/Wifx/gonetworkmanager ?
like https://pkg.go.dev/github.com/Wifx/gonetworkmanager#DHCP4Config

Or maybe raw https://github.com/godbus/dbus

For running in containers please mount the host dbus into the container. This can simply be done by adding -v /var/run/dbus:/var/run/dbus to your docker run command. Depending on what kind of permissions are required you may need to add --privileged to the command as well.

Please evaluate...

@glimchb
Copy link
Member Author

glimchb commented Jun 25, 2024

Chatgpt produced:

dbus.go example:

package main

import (
    "fmt"
    "github.com/godbus/dbus/v5"
)

func main() {
    // Connect to the system bus
    conn, err := dbus.SystemBus()
    if err != nil {
        panic(fmt.Errorf("failed to connect to system bus: %v", err))
    }

    // Get NetworkManager object
    nm := conn.Object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")

    // Get PrimaryConnection property from NetworkManager object
    var primaryConnPath dbus.ObjectPath
    err = nm.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager", "PrimaryConnection").Store(&primaryConnPath)
    if err != nil {
        panic(fmt.Errorf("failed to get PrimaryConnection property: %v", err))
    }

    // Get Active Connection object
    connActive := conn.Object("org.freedesktop.NetworkManager", primaryConnPath)

    // Get Dhcp4Config property from Active Connection object
    var dhcpPath dbus.ObjectPath
    err = connActive.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager.Connection.Active", "Dhcp4Config").Store(&dhcpPath)
    if err != nil {
        panic(fmt.Errorf("failed to get Dhcp4Config property: %v", err))
    }

    // Get Options property from DHCP4Config object
    dhcp := conn.Object("org.freedesktop.NetworkManager", dhcpPath)
    var options map[string]dbus.Variant
    err = dhcp.Call("org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.NetworkManager.DHCP4Config", "Options").Store(&options)
    if err != nil {
        panic(fmt.Errorf("failed to get Options property: %v", err))
    }

    // Print sztp_redirect_urls option
    sztpRedirectURLs := options["sztp_redirect_urls"].Value().(string)
    fmt.Println(sztpRedirectURLs)
}

or

nm,go example

package main

import (
	"fmt"
	"log"

	"github.com/Wifx/gonetworkmanager"
)

func main() {
	// Create a new NetworkManager client
	client, err := gonetworkmanager.NewClient()
	if err != nil {
		log.Fatalf("Failed to create NetworkManager client: %v", err)
	}

	// Get the active connection
	activeConnection, err := client.PrimaryConnection()
	if err != nil {
		log.Fatalf("Failed to get primary connection: %v", err)
	}

	// Get DHCP4 configuration
	dhcpConfig, err := activeConnection.DHCP4Config()
	if err != nil {
		log.Fatalf("Failed to get DHCP4 configuration: %v", err)
	}

	// Get options from DHCP4 configuration
	options, err := dhcpConfig.Options()
	if err != nil {
		log.Fatalf("Failed to get DHCP4 options: %v", err)
	}

	// Print sztp_redirect_urls option
	if sztpRedirectURLs, ok := options["sztp_redirect_urls"]; ok {
		fmt.Println(sztpRedirectURLs)
	} else {
		log.Println("sztp_redirect_urls option not found")
	}
}

tested first code snippet on bluefield2

$ cd sztp-agent
$ docker run  --rm -it -v `pwd`:/app -w /app golang:alpine go get github.com/godbus/dbus/v5
$ docker run  --rm -it --privileged -v `pwd`:/app -v /var/run/dbus:/var/run/dbus -w /app golang:alpine go run dbus.go
go: downloading github.com/godbus/dbus/v5 v5.1.0
https://bootstrap:8080/restconf/operations/ietf-sztp-bootstrap-server:get-bootstrapping-data

second code snippet is untested

@glimchb
Copy link
Member Author

glimchb commented Jun 25, 2024

this is untested for looping over active connections instead of just primary connection:

import dbus

bus = dbus.SystemBus()

# Get NetworkManager object
nm = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")

# Get ActiveConnections property from NetworkManager
active_connections_paths = nm.Get("org.freedesktop.NetworkManager", "ActiveConnections", dbus_interface="org.freedesktop.DBus.Properties")
active_connections = [bus.get_object("org.freedesktop.NetworkManager", path) for path in active_connections_paths]

# Iterate through each active connection
for active_connection in active_connections:
    # Get the DHCP configuration for the active connection
    dhcp_config_path = active_connection.Get("org.freedesktop.NetworkManager.Connection.Active", "Dhcp4Config", dbus_interface="org.freedesktop.DBus.Properties")
    dhcp_config_obj = bus.get_object("org.freedesktop.NetworkManager", dhcp_config_path)

    # Get DHCP options
    dhcp_options = dhcp_config_obj.Get("org.freedesktop.NetworkManager.DHCP4Config", "Options", dbus_interface="org.freedesktop.DBus.Properties")

    # Print the desired option
    print(str(dhcp_options["sztp_redirect_urls"]))

@glimchb
Copy link
Member Author

glimchb commented Jun 26, 2024

@bhoopesh369 do you want to take a stab with this issue ?

@bhoopesh369
Copy link
Contributor

@bhoopesh369 do you want to take a stab with this issue ?

Yep

@glimchb
Copy link
Member Author

glimchb commented Jun 26, 2024

assigned to @bhoopesh369
please check working dbus.go example above
we should do separate file/package for all dhcp work....

@glimchb glimchb changed the title fetch DHCP leases from nmcli fetch DHCP leases from nmcli o er dbus Jun 26, 2024
@glimchb glimchb changed the title fetch DHCP leases from nmcli o er dbus fetch DHCP leases from nmcli over dbus Jun 26, 2024
@bhoopesh369
Copy link
Contributor

i think going with github.com/Wifx/gonetworkmanager wont be future proof
so will proceed with dbus

@glimchb
Copy link
Member Author

glimchb commented Jun 27, 2024

so will proceed with dbus

agree

@glimchb
Copy link
Member Author

glimchb commented Jun 27, 2024

let's discuss also how we wat to expose this to user...

we will have 3 options:

  • bootstrap url provided - no need to discover
  • dhcp file provided - no need to dbus
  • dbus

agree or you have different algorithm ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants