First cut at nmvpn plugin

Signed-off-by: Jim Ramsay <i.am@jimramsay.com>
This commit is contained in:
Jim Ramsay 2022-07-29 23:07:01 -04:00 committed by Jim Ramsay
parent 904ba64ade
commit e10016d701
6 changed files with 188 additions and 0 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
# Binaries for programs and plugins
waybar-nmvpn
*.exe
*.exe~
*.dll

View file

@ -1,2 +1,47 @@
# waybar-nmvpn
Waybar plugin to display NetworkManager VPN status
## Installation
```
go install github.com/lack/waybar-nmvpn@latest
```
## Configuration
In `$XDG_CONFIG_HOME/waybar/config`
```json
{
// ... other waybar configuration
"custom/nmvpn": {
"format": "{} {icon}",
"return-type": "json",
"exec": "$GOPATH/bin/waybar-nmvpn",
"format-icons": {
"connected": "",
"disconnected": "",
"none": "",
"error": "⚠"
}
}
}
```
In `$XDG_CONFIG_HOME/waybar/style.css`
```css
#custom-nmvpn.connected {
background-color: rgba(0x29, 0x80, 0xb9, 0.8);
box-shadow: inset 0 -3px rgba(0x29, 0x80, 0xb9, 1.0);
}
#custom-nmvpn.disconnected {
background-color: rgba(0xf5, 0x3c, 0x3c, 0.8);
box-shadow: inset 0 -3px rgba(0xf5, 0x3c, 0x3c, 1.0);
}
#custom-nmvpn.error {
background-color: rgba(0xeb, 0x4d, 0x4b, 0.8);
box-shadow: inset 0 -3px rgba(0xeb, 0x4d, 0x4b, 1.0);
}
```

10
go.mod Normal file
View file

@ -0,0 +1,10 @@
module github.com/lack/waybar-nmvpn
go 1.18
require (
github.com/Wifx/gonetworkmanager v0.4.0
github.com/lack/gowaybarplug v0.0.1
)
require github.com/godbus/dbus/v5 v5.0.2 // indirect

11
go.sum Normal file
View file

@ -0,0 +1,11 @@
github.com/Wifx/gonetworkmanager v0.4.0 h1:iZ7o3z3YIqEEAa+bBOCwQkLLUQuxG02CdiE7NCe5y6A=
github.com/Wifx/gonetworkmanager v0.4.0/go.mod h1:EdhHf2O00IZXfMv9LC6CS6SgTwcMTg/ZSDhGvch0cs8=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/godbus/dbus/v5 v5.0.2 h1:QtWdZQyXTEn7S0LXv9nVxPUiT37d1i7UntpRTiKM86E=
github.com/godbus/dbus/v5 v5.0.2/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/lack/gowaybarplug v0.0.1 h1:v+ZURlUmXh1UXsEMQHAzBaojaRTrUmYUY+mJ7sOI/Yw=
github.com/lack/gowaybarplug v0.0.1/go.mod h1:JDAsRZJ0F337PSepC1prQUc+8NOdaqTqKjTYm3eR67Q=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/xorcare/pointer v1.1.0 h1:sFwXOhRF8QZ0tyVZrtxWGIoVZNEmRzBCaFWdONPQIUM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

62
main.go Normal file
View file

@ -0,0 +1,62 @@
package main
import (
"fmt"
"time"
"github.com/lack/waybar-nmvpn/pkg/nmvpn"
waybar "github.com/lack/gowaybarplug"
)
func loop(interval time.Duration) {
wb := waybar.NewUpdater()
for true {
status := waybar.Status{
Text: "VPN",
}
vpns, err := nmvpn.GetVPNs()
if err == nil && len(vpns) > 0 {
active := false
for _, v := range vpns {
if v.Active {
active = true
break
}
}
if active {
status.Alt = "connected"
status.Class = []string{"connected"}
} else {
status.Alt = "disconnected"
status.Class = []string{"disconnected"}
}
status.Tooltip = ""
for _, v := range vpns {
if status.Tooltip != "" {
status.Tooltip += "\n"
}
state := "down"
if v.Active {
state = "up"
}
status.Tooltip += fmt.Sprintf("%s: %s", v.Name, state)
}
} else if err != nil {
status.Alt = "error"
status.Class = []string{"error"}
status.Tooltip = fmt.Sprintf("Error fetching VPN information: %v", err)
} else {
status.Alt = "none"
status.Class = []string{"unconfigured"}
status.Tooltip = "No VPN connections configured"
}
wb.Status <- &status
time.Sleep(interval)
}
}
func main() {
loop(5 * time.Second)
}

59
pkg/nmvpn/nmvpn.go Normal file
View file

@ -0,0 +1,59 @@
package nmvpn
import (
gonm "github.com/Wifx/gonetworkmanager"
)
type Vpn struct {
Name string
Uuid string
Active bool
}
func GetVPNs() ([]Vpn, error) {
settings, err := gonm.NewSettings()
if err != nil {
return nil, err
}
connections, err := settings.ListConnections()
if err != nil {
return nil, err
}
vpns := make([]Vpn, 0, len(connections))
for _, c := range connections {
s, err := c.GetSettings()
if err != nil {
return nil, err
}
ctype := s["connection"]["type"].(string)
if ctype == "vpn" {
vpn := Vpn{
Name: s["connection"]["id"].(string),
Uuid: s["connection"]["uuid"].(string),
}
vpns = append(vpns, vpn)
}
}
if len(vpns) > 0 {
nm, err := gonm.NewNetworkManager()
if err != nil {
return nil, err
}
actives, err := nm.GetPropertyActiveConnections()
for _, a := range actives {
uuid, err := a.GetPropertyUUID()
if err != nil {
return nil, err
}
for i, v := range vpns {
if uuid == v.Uuid {
vpns[i].Active = true
}
}
}
}
return vpns, nil
}