112 lines
2.1 KiB
Go
112 lines
2.1 KiB
Go
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
|
|
"github.com/Neur0toxine/sshpoke/internal/config"
|
|
"github.com/Neur0toxine/sshpoke/internal/logger"
|
|
"github.com/Neur0toxine/sshpoke/internal/model"
|
|
"github.com/Neur0toxine/sshpoke/internal/server/driver/iface"
|
|
"github.com/Neur0toxine/sshpoke/internal/server/driver/util"
|
|
)
|
|
|
|
// Plugin driver uses RPC to communicate with external plugin.
|
|
type Plugin struct {
|
|
ctx context.Context
|
|
name string
|
|
params Params
|
|
send chan model.Event
|
|
}
|
|
|
|
type EventStream interface {
|
|
Send(event model.Event) error
|
|
Recv() error
|
|
}
|
|
|
|
func New(ctx context.Context, name string, params config.DriverParams) (iface.Driver, error) {
|
|
drv := &Plugin{
|
|
name: name,
|
|
ctx: ctx,
|
|
send: make(chan model.Event),
|
|
}
|
|
if err := util.UnmarshalParams(params, &drv.params); err != nil {
|
|
return nil, err
|
|
}
|
|
return drv, nil
|
|
}
|
|
|
|
func (d *Plugin) Handle(event model.Event) error {
|
|
if d.isDone() {
|
|
return nil
|
|
}
|
|
d.send <- event
|
|
return nil
|
|
}
|
|
|
|
func (d *Plugin) Name() string {
|
|
return d.name
|
|
}
|
|
|
|
func (d *Plugin) Driver() config.DriverType {
|
|
return config.DriverPlugin
|
|
}
|
|
|
|
func (d *Plugin) Token() string {
|
|
return d.params.Token
|
|
}
|
|
|
|
func (d *Plugin) Listen(ctx context.Context, stream EventStream) error {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil
|
|
default:
|
|
}
|
|
|
|
err := stream.Recv()
|
|
if errors.Is(err, io.EOF) {
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
logger.Sugar.Errorw("error reading poll event from plugin",
|
|
"server", d.name, "error", err)
|
|
return err
|
|
}
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil
|
|
case event := <-d.send:
|
|
err := stream.Send(event)
|
|
if errors.Is(err, io.EOF) {
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
logger.Sugar.Errorw("error writing event to plugin",
|
|
"server", d.name, "error", err)
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (d *Plugin) HandleStatus(event model.EventRequest) {
|
|
logger.Sugar.Errorw("plugin error", "serverName", d.name, "id", event.ID, "error", event.Error)
|
|
}
|
|
|
|
func (d *Plugin) isDone() bool {
|
|
select {
|
|
case <-d.ctx.Done():
|
|
close(d.send)
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (d *Plugin) WaitForShutdown() {
|
|
<-d.ctx.Done()
|
|
return
|
|
}
|