dhcp4d: optionally publish DHCP leases to MQTT
Enable using: mkdir -p /perm/dhcp4d echo 'tcp://10.0.0.54:1883' > /perm/dhcp4d/mqtt-broker.txt
This commit is contained in:
parent
e5ea79aef8
commit
04f2be01d9
@ -234,6 +234,8 @@ type srv struct {
|
||||
}
|
||||
|
||||
func newSrv(permDir string) (*srv, error) {
|
||||
mayqtt := MQTT()
|
||||
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
if err := updateListeners(); err != nil {
|
||||
return nil, err
|
||||
@ -399,6 +401,30 @@ func newSrv(permDir string) (*srv, error) {
|
||||
if err := notify.Process("/user/dnsd", syscall.SIGUSR1); err != nil {
|
||||
log.Printf("notifying dnsd: %v", err)
|
||||
}
|
||||
|
||||
// Publish the DHCP lease as JSON to MQTT, if configured:
|
||||
leaseVal := struct {
|
||||
Addr string `json:"addr"`
|
||||
HardwareAddr string `json:"hardware_addr"`
|
||||
Expiration time.Time `json:"expiration"`
|
||||
}{
|
||||
Addr: latest.Addr.String(),
|
||||
HardwareAddr: latest.HardwareAddr,
|
||||
Expiration: latest.Expiry.In(time.UTC),
|
||||
}
|
||||
leaseJSON, err := json.Marshal(leaseVal)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
identifier := latest.Hostname
|
||||
if identifier == "" {
|
||||
identifier = latest.HardwareAddr
|
||||
}
|
||||
mayqtt <- PublishRequest{
|
||||
Topic: "router7/dhcp4d/lease/" + identifier,
|
||||
Retained: true,
|
||||
Payload: leaseJSON,
|
||||
}
|
||||
}
|
||||
conn, err := conn.NewUDP4BoundListener(*iface, ":67")
|
||||
if err != nil {
|
||||
|
53
cmd/dhcp4d/mayqtt.go
Normal file
53
cmd/dhcp4d/mayqtt.go
Normal file
@ -0,0 +1,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
)
|
||||
|
||||
type PublishRequest struct {
|
||||
Topic string
|
||||
Qos byte
|
||||
Retained bool
|
||||
Payload interface{}
|
||||
}
|
||||
|
||||
func publisherLoop(requests <-chan PublishRequest) error {
|
||||
const configFn = "/perm/dhcp4d/mqtt-broker.txt"
|
||||
b, err := ioutil.ReadFile(configFn)
|
||||
if err != nil {
|
||||
// discard requests:
|
||||
for range requests {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// e.g. tcp://10.0.0.54:1883, which is a static DHCP lease for the dr.lan
|
||||
// Raspberry Pi, which is running an MQTT broker in my network.
|
||||
broker := strings.TrimSpace(string(b))
|
||||
log.Printf("Connecting to MQTT broker %q (configured in %s)", broker, configFn)
|
||||
opts := mqtt.NewClientOptions().AddBroker(broker)
|
||||
opts.SetClientID("dhcp4d")
|
||||
mqttClient := mqtt.NewClient(opts)
|
||||
if token := mqttClient.Connect(); token.Wait() && token.Error() != nil {
|
||||
return fmt.Errorf("MQTT connection failed: %v", token.Error())
|
||||
}
|
||||
|
||||
for r := range requests {
|
||||
// discard Token, MQTT publishing is best-effort
|
||||
_ = mqttClient.Publish(r.Topic, r.Qos, r.Retained, r.Payload)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func MQTT() chan<- PublishRequest {
|
||||
result := make(chan PublishRequest)
|
||||
go func() {
|
||||
if err := publisherLoop(result); err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
}()
|
||||
return result
|
||||
}
|
1
go.mod
1
go.mod
@ -7,6 +7,7 @@ require (
|
||||
github.com/digineo/go-ping v1.0.0
|
||||
github.com/gokrazy/breakglass v0.0.0-20200527163858-efff2172eebe // indirect
|
||||
github.com/gokrazy/gdns v0.0.0-20200218203540-6b3b6244ea39 // indirect
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0
|
||||
github.com/gokrazy/gokrazy v0.0.0-20201006151115-caded4667633
|
||||
github.com/gokrazy/internal v0.0.0-20200713084155-ab6fc6e02a03 // indirect
|
||||
github.com/gokrazy/timestamps v0.0.0-20200713073712-54fdc319126e // indirect
|
||||
|
1
go.sum
1
go.sum
@ -70,6 +70,7 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
|
Loading…
x
Reference in New Issue
Block a user