Skip to content
Snippets Groups Projects
Commit ed46c205 authored by Malte Bauch's avatar Malte Bauch
Browse files

Provide access to gosdn events through websockets application

parent ceef13c5
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !490. Comments created here will be created in the context of that merge request.
......@@ -110,6 +110,9 @@ build-hostname-checker-app: pre
build-basic-interface-monitoring-app: pre
$(GOBUILD) -trimpath -o $(BUILD_ARTIFACTS_PATH)/basic-interface-monitoring ./applications/basic-interface-monitoring
build-ws-events-app: pre
$(GOBUILD) -trimpath -o $(BUILD_ARTIFACTS_PATH)/ws-events ./applications/ws-events
containerize-all: containerize-gosdn containerize-gosdnc containerize-plugin-registry containerize-target
containerize-slim: containerize-gosdn containerize-gosdnc containerize-plugin-registry
......@@ -138,6 +141,9 @@ containerize-arista-routing-engine-app:
containerize-hostname-checker-app:
docker buildx build --rm -t hostname-checker-app -f applications/hostname-checker/hostname-checker.Dockerfile .
containerize-ws-events-app:
docker buildx build --rm -t ws-events-app -f applications/ws-events/ws-events.Dockerfile .
containerlab-start: create-clab-dir containerize-all
cd $(CLAB_DIR) &&\
sudo containerlab deploy --topo $(MAKEFILE_DIR)dev_env_data/clab/gosdn.clab.yaml
......
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"code.fbi.h-da.de/danet/gosdn/application-framework/event"
"github.com/lesismal/nbio/nbhttp"
"github.com/sirupsen/logrus"
)
// Application is an example for a sdn application.
type Application struct {
eventService event.ServiceInterface
stopChannel chan os.Signal
}
// Run runs the application.
func (a *Application) Run() {
signal.Notify(a.stopChannel, os.Interrupt, syscall.SIGTERM)
a.eventService.SubscribeToEventType([]event.TypeToCallbackTuple{
{Type: event.Add, Callback: a.callback},
{Type: event.Delete, Callback: a.callback},
{Type: event.Update, Callback: a.callback},
})
a.eventService.SetupEventReciever(a.stopChannel)
mux := &http.ServeMux{}
mux.HandleFunc("/events", onWebsocket)
svr := nbhttp.NewServer(nbhttp.Config{
Network: "tcp",
Addrs: []string{"localhost:80"},
Handler: mux,
})
err := svr.Start()
if err != nil {
fmt.Printf("Server start failed: %v\n", err)
return
}
<-a.stopChannel
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
svr.Shutdown(ctx)
}
func (a *Application) callback(event *event.Event) {
b, err := json.Marshal(event)
if err != nil {
logrus.Error("Failed marshal of event")
}
clientManager.Publish(b)
}
package main
import (
"os"
"code.fbi.h-da.de/danet/gosdn/application-framework/event"
"code.fbi.h-da.de/danet/gosdn/application-framework/registration"
"github.com/sirupsen/logrus"
)
func main() {
queueCredentials, err := registration.Register("localhost:55055", "ws-events", "SecurePresharedToken")
if err != nil {
logrus.Errorf("failed to register application on control plane. %v", err)
os.Exit(1)
}
eventService, err := event.NewEventService(
queueCredentials,
[]event.Topic{event.ManagedNetworkElement},
)
if err != nil {
logrus.Errorf("failed to create event service. %v", err)
os.Exit(1)
}
app := &Application{
eventService: eventService,
stopChannel: make(chan os.Signal, 1),
}
app.Run()
}
ARG GOLANG_VERSION=1.20.5
ARG BUILDARGS
ARG $GITLAB_PROXY
FROM ${GITLAB_PROXY}golang:$GOLANG_VERSION-alpine as builder
WORKDIR /app/
RUN apk add --no-cache build-base
RUN apk add --no-cache bash
COPY . .
RUN --mount=type=cache,target=/root/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
make build-ws-events-app
FROM scratch
COPY --from=builder /app/artifacts/ws-events /app/artifacts/ws-events
ENTRYPOINT ["./artifacts/ws-events"]
.git
.gitlab
build
documentation
mocks
test
clab-gosdn_csbi_arista_base
clab-gosdn_sts_demo_basic
.cobra.yaml
.dockeringore
.gitlab-ci.yaml
ARCHITECTURE.md
CONTRIBUTING.md
README.md
artifacts
build-tools
cli
config
csbi
dev_env_data
docker_volume_backup
docs
documentation
forks
lab-vm
models
plugin-registry
plugins
scripts
package main
import (
"net/http"
"time"
"github.com/lesismal/nbio/nbhttp/websocket"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
)
var (
clientManager = NewClientManager()
keepaliveTimer = time.Second * 30
)
type ClientManager struct {
clients map[*websocket.Conn]struct{}
}
func (cMngr *ClientManager) Register(client *websocket.Conn) {
cMngr.clients[client] = struct{}{}
logrus.Println("Added new client: ", client.RemoteAddr())
}
func (cMngr *ClientManager) Deregister(client *websocket.Conn) {
delete(cMngr.clients, client)
logrus.Println("Removed client: ", client.RemoteAddr())
}
func (cMngr *ClientManager) Publish(message []byte) {
var eg errgroup.Group
for c := range cMngr.clients {
eg.Go(func() error {
logrus.Println("Publishing to client", c.RemoteAddr())
return c.WriteMessage(websocket.TextMessage, message)
})
if err := eg.Wait(); err != nil {
logrus.Printf("Websocket failed to broadcast message to: %s, %v\n", c.Conn.RemoteAddr().String(), err)
}
}
}
func NewClientManager() *ClientManager {
return &ClientManager{
clients: make(map[*websocket.Conn]struct{}),
}
}
func newUpgrader() *websocket.Upgrader {
u := websocket.NewUpgrader()
u.OnOpen(func(c *websocket.Conn) {
clientManager.Register(c)
})
u.OnClose(func(c *websocket.Conn, err error) {
clientManager.Deregister(c)
})
u.OnMessage(func(c *websocket.Conn, messageType websocket.MessageType, data []byte) {
c.SetReadDeadline(time.Now().Add(keepaliveTimer))
})
return u
}
func onWebsocket(w http.ResponseWriter, r *http.Request) {
upgrader := newUpgrader()
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logrus.Println("Could not create websocket")
return
}
conn.SetReadDeadline(time.Now().Add(keepaliveTimer))
}
......@@ -90,6 +90,7 @@ require (
require (
github.com/hashicorp/go-plugin v1.4.10
github.com/lesismal/nbio v1.3.17
google.golang.org/genproto/googleapis/api v0.0.0-20230807174057-1744710a1577
)
......@@ -101,6 +102,7 @@ require (
github.com/fatih/color v1.15.0 // indirect
github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/lesismal/llib v1.1.12 // indirect
github.com/lithammer/fuzzysearch v1.1.7 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/moby/patternmatcher v0.5.0 // indirect
......
......@@ -628,6 +628,10 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lesismal/llib v1.1.12 h1:KJFB8bL02V+QGIvILEw/w7s6bKj9Ps9Px97MZP2EOk0=
github.com/lesismal/llib v1.1.12/go.mod h1:70tFXXe7P1FZ02AU9l8LgSOK7d7sRrpnkUr3rd3gKSg=
github.com/lesismal/nbio v1.3.17 h1:rsDwVdRfFK/QcFckDBgdGIZTf6Y98XWHRQWDY+EldO8=
github.com/lesismal/nbio v1.3.17/go.mod h1:KWlouFT5cgDdW5sMX8RsHASUMGniea9X0XIellZ0B38=
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
github.com/lithammer/fuzzysearch v1.1.7 h1:q8rZNmBIUkqxsxb/IlwsXVbCoPIH/0juxjFHY0UIwhU=
github.com/lithammer/fuzzysearch v1.1.7/go.mod h1:ZhIlfRGxnD8qa9car/yplC6GmnM14CS07BYAKJJBK2I=
......@@ -1073,10 +1077,12 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210513122933-cd7d49e622d5/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
......@@ -1169,6 +1175,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment