Newer
Older
package nucleus
import (
"context"
"fmt"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/device"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/types"
"code.fbi.h-da.de/danet/gosdn/forks/goarista/gnmi"
gpb "github.com/openconfig/gnmi/proto/gnmi"
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
log "github.com/sirupsen/logrus"
)
const (
subscribeSampleInterval uint64 = 1000000000 // 1 second in nanoseconds
// TODO: These gNMI options are adjusted to arista gNMI fork. Change when switching to native gNMI
gNMISubscribeMode string = "stream"
gNMIStreamMode string = "sample"
)
// DeviceWatcher is a component that subscribes to devices via gNMI from within the controller and handles
// responses by triggering the internal event process.
type DeviceWatcher struct {
pndStore networkdomain.PndStore
}
// NewDeviceWatcher takes a pndStore to subscribe to device paths.
func NewDeviceWatcher(pndStore networkdomain.PndStore) *DeviceWatcher {
return &DeviceWatcher{
pndStore: pndStore,
}
}
// SubToDevices subscribes to every available device in each network domain with fixed gNMI subscription options (streaming in sample mode each second).
// Paths should be provided in the following format [][]string{{"system", "config", "hostname"}}
func (d *DeviceWatcher) SubToDevices(paths [][]string) {
opts := &gnmi.SubscribeOptions{
Mode: gNMISubscribeMode,
StreamMode: gNMIStreamMode,
Paths: paths,
SampleInterval: subscribeSampleInterval,
}
pnds, err := d.pndStore.GetAll()
if err != nil {
log.Error(err)
}
for _, pnd := range pnds {
d.subscribeToPndDevices(pnd, opts)
}
}
func (d *DeviceWatcher) subscribeToPndDevices(pnd networkdomain.NetworkDomain, opts *gnmi.SubscribeOptions) {
for _, device := range pnd.Devices() {
go d.callSubscribe(device, opts)
}
}
func (d *DeviceWatcher) callSubscribe(device device.Device, opts *gnmi.SubscribeOptions) {
ctx := context.Background()
ctx = context.WithValue(ctx, types.CtxKeyOpts, opts)
if err := device.Transport().SubscribeInternal(ctx, handleSubscribeRepsonse); err != nil {
logrus.Error(err)
}
}
func handleSubscribeRepsonse(resp *gpb.SubscribeResponse) {
fmt.Printf("YEP HANDLER CALLED Type:%T ExampleMessage:%s\n", resp, resp.String())
}