Add commands to list sinks and to read a protocol file to JSON

This commit is contained in:
Peter 2021-01-20 18:39:57 +01:00
parent a76d1d1c04
commit 66f2aab9af
Signed by: prskr
GPG key ID: C1DB5D2E8DB512F9
6 changed files with 146 additions and 75 deletions

View file

@ -36,8 +36,17 @@ message RemoveFileSinkResponse {
bool SinkGotRemoved = 1;
}
message ListSinksRequest {
}
message ListSinksResponse {
repeated string sinks = 1;
}
service Audit {
rpc WatchEvents (WatchEventsRequest) returns (stream inetmock.audit.EventEntity);
rpc RegisterFileSink (RegisterFileSinkRequest) returns (RegisterFileSinkResponse);
rpc RemoveFileSink (RemoveFileSinkRequest) returns (RemoveFileSinkResponse);
rpc ListSinks(ListSinksRequest) returns (ListSinksResponse);
}

View file

@ -1,63 +0,0 @@
package main
import (
"context"
"fmt"
"os"
"github.com/spf13/cobra"
"gitlab.com/inetmock/inetmock/internal/rpc"
"google.golang.org/grpc"
)
var (
addFileCmd = &cobra.Command{
Use: "addFile",
Short: "subscribe events to a file",
Args: cobra.ExactArgs(1),
RunE: runAddFile,
}
removeFileCmd = &cobra.Command{
Use: "removeFile",
Short: "remove file subscription",
Args: cobra.ExactArgs(1),
RunE: runRemoveFile,
}
readFileCmd = &cobra.Command{
Use: "readFile",
Short: "reads an audit file and prints the events",
Args: cobra.ExactArgs(1),
RunE: runReadFile,
}
)
func runAddFile(_ *cobra.Command, args []string) (err error) {
var conn *grpc.ClientConn
if conn, err = grpc.Dial(inetMockSocketPath, grpc.WithInsecure()); err != nil {
fmt.Printf("Failed to connecto INetMock socket: %v\n", err)
os.Exit(10)
}
auditClient := rpc.NewAuditClient(conn)
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
defer cancel()
_, err = auditClient.RegisterFileSink(ctx, &rpc.RegisterFileSinkRequest{TargetPath: args[0]})
return
}
func runRemoveFile(_ *cobra.Command, args []string) (err error) {
auditClient := rpc.NewAuditClient(conn)
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
defer cancel()
_, err = auditClient.RemoveFileSink(ctx, &rpc.RemoveFileSinkRequest{TargetPath: args[0]})
return
}
func runReadFile(_ *cobra.Command, args []string) (err error) {
return
}

118
cmd/imctl/audit_sinks.go Normal file
View file

@ -0,0 +1,118 @@
package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"github.com/spf13/cobra"
"gitlab.com/inetmock/inetmock/internal/format"
"gitlab.com/inetmock/inetmock/internal/rpc"
"gitlab.com/inetmock/inetmock/pkg/audit"
)
var (
listSinksCmd = &cobra.Command{
Use: "list",
Aliases: []string{"ls", "dir"},
Short: "List all subscribed sinks",
RunE: runListSinks,
}
addFileCmd = &cobra.Command{
Use: "add-file",
Aliases: []string{"add"},
Short: "subscribe events to a file",
Args: cobra.ExactArgs(1),
RunE: runAddFile,
}
removeFileCmd = &cobra.Command{
Use: "remove-file",
Aliases: []string{"rm", "del"},
Short: "remove file subscription",
Args: cobra.ExactArgs(1),
RunE: runRemoveFile,
}
readFileCmd = &cobra.Command{
Use: "read-file",
Aliases: []string{"cat"},
Short: "reads an audit file and prints the events",
Args: cobra.ExactArgs(1),
RunE: runReadFile,
}
)
type printableSink struct {
Name string
}
func runListSinks(*cobra.Command, []string) (err error) {
auditClient := rpc.NewAuditClient(conn)
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
defer cancel()
var resp *rpc.ListSinksResponse
if resp, err = auditClient.ListSinks(ctx, &rpc.ListSinksRequest{}); err != nil {
return
}
var sinks []printableSink
for _, s := range resp.Sinks {
sinks = append(sinks, printableSink{Name: s})
}
writer := format.Writer(outputFormat, os.Stdout)
err = writer.Write(sinks)
return
}
func runAddFile(_ *cobra.Command, args []string) (err error) {
auditClient := rpc.NewAuditClient(conn)
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
defer cancel()
_, err = auditClient.RegisterFileSink(ctx, &rpc.RegisterFileSinkRequest{TargetPath: args[0]})
return
}
func runRemoveFile(_ *cobra.Command, args []string) (err error) {
auditClient := rpc.NewAuditClient(conn)
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
defer cancel()
_, err = auditClient.RemoveFileSink(ctx, &rpc.RemoveFileSinkRequest{TargetPath: args[0]})
return
}
func runReadFile(_ *cobra.Command, args []string) (err error) {
if len(args) != 1 {
return errors.New("expected only 1 argument")
}
var reader io.ReadCloser
if reader, err = os.Open(args[0]); err != nil {
return
}
eventReader := audit.NewEventReader(reader)
var ev audit.Event
for err == nil {
if ev, err = eventReader.Read(); err == nil {
var jsonBytes []byte
if jsonBytes, err = json.Marshal(ev); err == nil {
fmt.Println(string(jsonBytes))
}
}
}
if errors.Is(err, io.EOF) {
err = nil
}
return
}

View file

@ -25,7 +25,7 @@ var (
)
type printableEndpoint struct {
Id string
ID string
Name string
Handler string
ListenAddress string
@ -34,7 +34,7 @@ type printableEndpoint struct {
func fromEndpoint(ep *rpc.Endpoint) *printableEndpoint {
return &printableEndpoint{
Id: ep.Id,
ID: ep.Id,
Name: ep.Name,
Handler: ep.Handler,
ListenAddress: ep.ListenAddress,

View file

@ -2,6 +2,8 @@ package main
import (
"context"
"fmt"
"os"
"os/user"
"time"
@ -20,7 +22,6 @@ var (
)
func main() {
endpointsCmd.AddCommand(getEndpoints)
handlerCmd.AddCommand(getHandlersCmd)
healthCmd.AddCommand(generalHealthCmd, containerHealthCmd)
@ -29,7 +30,8 @@ func main() {
WithCommands(endpointsCmd, handlerCmd, healthCmd, auditCmd).
WithInitTasks(func(_ *cobra.Command, _ []string) (err error) {
return initGRPCConnection()
})
}).
WithLogger()
cliApp.RootCommand().PersistentFlags().StringVar(&inetMockSocketPath, "socket-path", "unix:///var/run/inetmock.sock", "Path to the INetMock socket file")
cliApp.RootCommand().PersistentFlags().StringVarP(&outputFormat, "format", "f", "table", "Output format to use. Possible values: table, json, yaml")
@ -42,16 +44,15 @@ func main() {
currentUser = uuid.New().String()
}
watchEventsCmd.PersistentFlags().StringVar(
&listenerName,
"listener-name",
currentUser,
"set listener name - defaults to the current username, if the user cannot be determined a random UUID will be used",
)
auditCmd.AddCommand(watchEventsCmd, addFileCmd, removeFileCmd)
hostname := "."
if hn, err := os.Hostname(); err == nil {
hostname = hn
}
watchEventsCmd.PersistentFlags().StringVar(&listenerName, "listener-name", fmt.Sprintf("%s\\%s is watching", hostname, currentUser), "set listener name - defaults to the current username, if the user cannot be determined a random UUID will be used")
auditCmd.AddCommand(listSinksCmd, watchEventsCmd, addFileCmd, removeFileCmd, readFileCmd)
cliApp.MustRun()
}
func initGRPCConnection() (err error) {

View file

@ -17,6 +17,12 @@ type auditServer struct {
eventStream audit.EventStream
}
func (a *auditServer) ListSinks(context.Context, *ListSinksRequest) (*ListSinksResponse, error) {
return &ListSinksResponse{
Sinks: a.eventStream.Sinks(),
}, nil
}
func (a *auditServer) WatchEvents(req *WatchEventsRequest, srv Audit_WatchEventsServer) (err error) {
a.logger.Info("watcher attached", zap.String("name", req.WatcherName))
err = a.eventStream.RegisterSink(sink.NewGRPCSink(srv.Context(), req.WatcherName, func(ev audit.Event) {