Skip to content

Commit

Permalink
Merge pull request #1 from leberKleber/device-status
Browse files Browse the repository at this point in the history
feat: handle device status
  • Loading branch information
leberKleber committed Dec 29, 2023
2 parents f0cb817 + e2c1e5b commit 5bcf6a3
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 26 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ The library can be used in a `nmcli` like scheme.

### Networking

| original command | library path | implemented |
|-------------------------------------|----------------------------------|-------------------------------|
| `nmcli networking ...` | not implemented yet | :negative_squared_cross_mark: |
| original command | library path | implemented |
|------------------------|---------------------|-------------------------------|
| `nmcli networking ...` | not implemented yet | :negative_squared_cross_mark: |

### Radio

| original command | library path | implemented |
|-------------------------------------|----------------------------------|-------------------------------|
| `nmcli radio ...` | not implemented yet | :negative_squared_cross_mark: |
| original command | library path | implemented |
|-------------------|---------------------|-------------------------------|
| `nmcli radio ...` | not implemented yet | :negative_squared_cross_mark: |

### Device

| original command | library path | implemented |
|-----------------------------------|--------------------------------------|-------------------------------|
| `nmcli device status` | `NMCli.Device.Status(...)` | :negative_squared_cross_mark: |
| `nmcli device status` | `NMCli.Device.Status(...)` | :heavy_check_mark: |
| `nmcli device show` | `NMCli.Device.Show(...)` | :negative_squared_cross_mark: |
| `nmcli device set` | `NMCli.Device.Set(...)` | :negative_squared_cross_mark: |
| `nmcli device reapply` | `NMCli.Device.Reapply(...)` | :negative_squared_cross_mark: |
Expand All @@ -46,14 +46,14 @@ The library can be used in a `nmcli` like scheme.

### Agent

| original command | library path | implemented |
|-------------------------------------|----------------------------------|-------------------------------|
| `nmcli agent ...` | not implemented yet | :negative_squared_cross_mark: |
| original command | library path | implemented |
|-------------------|---------------------|-------------------------------|
| `nmcli agent ...` | not implemented yet | :negative_squared_cross_mark: |

### Monitor

| original command | library path | implemented |
|-------------------------------------|----------------------------------|-------------------------------|
| `nmcli monitor ...` | not implemented yet | :negative_squared_cross_mark: |
| original command | library path | implemented |
|---------------------|---------------------|-------------------------------|
| `nmcli monitor ...` | not implemented yet | :negative_squared_cross_mark: |

## Usage
56 changes: 56 additions & 0 deletions device/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package device

import (
"context"
"fmt"
"strings"

"github.com/leberKleber/go-nmcli/utils"
)

type Status struct {
Device string
Type string
State string
IP4Connectivity string
IP6Connectivity string
DbusPath string
Connection string
ConUUID string
ConPath string
}

// Status lists the status for all devices.
func (m Manager) Status(ctx context.Context) ([]Status, error) {
fields := []string{"DEVICE", "TYPE", "STATE", "IP4-CONNECTIVITY", "IP6-CONNECTIVITY", "DBUS-PATH", "CONNECTION", "CON-UUID", "CON-PATH"}

cmdArgs := []string{"-g", strings.Join(fields, ",")}
cmdArgs = append(cmdArgs, "device", "status")

output, err := m.CommandContext(ctx, nmcliCmd, cmdArgs...).Output()
if err != nil {
return nil, fmt.Errorf("failed to execute nmcli with args %+q: %w", cmdArgs, err)
}

parsedOutput, err := utils.ParseCmdOutput(output, len(fields))
if err != nil {
return nil, fmt.Errorf("failed to parse nmcli output: %w", err)
}

statuss := make([]Status, len(parsedOutput))
for i, fields := range parsedOutput {
statuss[i] = Status{
Device: fields[0],
Type: fields[1],
State: fields[2],
IP4Connectivity: fields[3],
IP6Connectivity: fields[4],
DbusPath: fields[5],
Connection: fields[6],
ConUUID: fields[7],
ConPath: fields[8],
}
}

return statuss, nil
}
80 changes: 80 additions & 0 deletions device/status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package device_test

import (
"context"
"testing"

"github.com/golang/mock/gomock"
"github.com/leberKleber/go-nmcli/device"
"github.com/leberKleber/go-nmcli/utils"
"github.com/stretchr/testify/require"
)

func TestManager_Status(t *testing.T) {
ctrl := gomock.NewController(t)

mockedCmd := NewMockCmd(ctrl)
mockedCmd.EXPECT().Output().Return([]byte(`wlp0s20f3:wifi:connected:full:limited:/org/freedesktop/NetworkManager/Devices/3:FRITZ!Box 7530 NT:c29400e9-b18d-4d33-aa63-bed67d06fe6d:/org/freedesktop/NetworkManager/ActiveConnection/34
lo:loopback:connected (externally):unknown:unknown:/org/freedesktop/NetworkManager/Devices/1:lo:71cd44a9-9cd8-4c8b-9875-46ca760647c2:/org/freedesktop/NetworkManager/ActiveConnection/1
p2p-dev-wlp0s20f3:wifi-p2p:disconnected:none:none:/org/freedesktop/NetworkManager/Devices/69:::
enp0s31f6:ethernet:unavailable:none:none:/org/freedesktop/NetworkManager/Devices/2:::`), nil).Times(1)

m := device.Manager{
CommandContext: func(ctx context.Context, name string, args ...string) utils.Cmd {
require.Equal(t, "nmcli", name)
require.EqualValues(t,
[]string{"-g", "DEVICE,TYPE,STATE,IP4-CONNECTIVITY,IP6-CONNECTIVITY,DBUS-PATH,CONNECTION,CON-UUID,CON-PATH", "device", "status"},
args,
)

return mockedCmd
},
}

statuss, err := m.Status(context.Background())

require.NoError(t, err)
require.EqualValues(t, []device.Status{
{
Device: "wlp0s20f3",
Type: "wifi",
State: "connected",
IP4Connectivity: "full",
IP6Connectivity: "limited",
DbusPath: "/org/freedesktop/NetworkManager/Devices/3",
Connection: "FRITZ!Box 7530 NT",
ConUUID: "c29400e9-b18d-4d33-aa63-bed67d06fe6d",
ConPath: "/org/freedesktop/NetworkManager/ActiveConnection/34",
}, {
Device: "lo",
Type: "loopback",
State: "connected (externally)",
IP4Connectivity: "unknown",
IP6Connectivity: "unknown",
DbusPath: "/org/freedesktop/NetworkManager/Devices/1",
Connection: "lo",
ConUUID: "71cd44a9-9cd8-4c8b-9875-46ca760647c2",
ConPath: "/org/freedesktop/NetworkManager/ActiveConnection/1",
}, {
Device: "p2p-dev-wlp0s20f3",
Type: "wifi-p2p",
State: "disconnected",
IP4Connectivity: "none",
IP6Connectivity: "none",
DbusPath: "/org/freedesktop/NetworkManager/Devices/69",
Connection: "",
ConUUID: "",
ConPath: "",
}, {
Device: "enp0s31f6",
Type: "ethernet",
State: "unavailable",
IP4Connectivity: "none",
IP6Connectivity: "none",
DbusPath: "/org/freedesktop/NetworkManager/Devices/2",
Connection: "",
ConUUID: "",
ConPath: "",
},
}, statuss)
}
25 changes: 14 additions & 11 deletions device/wifi.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package device
import (
"context"
"fmt"
"github.com/leberKleber/go-nmcli/utils"
"strings"

"github.com/leberKleber/go-nmcli/utils"
)

type WiFiListOptions struct {
Expand All @@ -15,7 +16,7 @@ type WiFiListOptions struct {

type WiFiListOptionsRescan string

var (
const (
WiFiListOptionsRescanAuto WiFiListOptionsRescan = "auto"
WiFiListOptionsRescanYes WiFiListOptionsRescan = "yes"
WiFiListOptionsRescanNo WiFiListOptionsRescan = "no"
Expand Down Expand Up @@ -51,7 +52,7 @@ type WiFi struct {
DBusPath string
}

// WiFiList List available Wi-Fi access points.
// WiFiList list available Wi-Fi access points.
// The IfName and BSSID options can be used to list APs for a particular interface, or with a specific BSSID.
// The Rescan flag tells whether a new Wi-Fi scan should be triggered.
func (m Manager) WiFiList(ctx context.Context, args WiFiListOptions) ([]WiFi, error) {
Expand All @@ -71,9 +72,9 @@ func (m Manager) WiFiList(ctx context.Context, args WiFiListOptions) ([]WiFi, er
return nil, fmt.Errorf("failed to parse nmcli output: %w", err)
}

var wifis []WiFi
for _, fields := range parsedOutput {
wifis = append(wifis, WiFi{
wifis := make([]WiFi, len(parsedOutput))
for i, fields := range parsedOutput {
wifis[i] = WiFi{
Name: fields[0],
SSID: fields[1],
SSIDHEX: fields[2],
Expand All @@ -91,7 +92,7 @@ func (m Manager) WiFiList(ctx context.Context, args WiFiListOptions) ([]WiFi, er
Active: fields[14],
InUse: fields[15],
DBusPath: fields[16],
})
}
}

return wifis, nil
Expand All @@ -107,11 +108,13 @@ type WiFiConnectOptions struct {
Hidden WiFiConnectOptionsHidden
}

type WiFiConnectOptionsWEPKeyType string
type WiFiConnectOptionsPrivate string
type WiFiConnectOptionsHidden string
type (
WiFiConnectOptionsWEPKeyType string
WiFiConnectOptionsPrivate string
WiFiConnectOptionsHidden string
)

var (
const (
WiFiConnectOptionsWEPKeyTypeKey WiFiConnectOptionsWEPKeyType = "key"
WiFiConnectOptionsWEPKeyTypePhrase WiFiConnectOptionsWEPKeyType = "phrase"
WiFiConnectOptionsPrivateYes WiFiConnectOptionsPrivate = "yes"
Expand Down
3 changes: 2 additions & 1 deletion device/wifi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package device_test

import (
"context"
"testing"

"github.com/golang/mock/gomock"
"github.com/leberKleber/go-nmcli/device"
"github.com/leberKleber/go-nmcli/utils"
"github.com/stretchr/testify/require"
"testing"
)

func TestManager_WiFiList(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion nmcli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package go_nmcli

import (
"context"
"github.com/leberKleber/go-nmcli/device"
"os/exec"

"github.com/leberKleber/go-nmcli/device"

"github.com/leberKleber/go-nmcli/general"
"github.com/leberKleber/go-nmcli/utils"
"github.com/sirupsen/logrus"
Expand All @@ -18,6 +19,7 @@ type General interface {
type Device interface {
WiFiList(ctx context.Context, args device.WiFiListOptions) ([]device.WiFi, error)
WiFiConnect(ctx context.Context, BSSID string, args device.WiFiConnectOptions) (string, error)
Status(ctx context.Context) ([]device.Status, error)
}

type NMCli struct {
Expand Down

0 comments on commit 5bcf6a3

Please sign in to comment.