Add commands to list sinks and to read a protocol file to JSON
This commit is contained in:
parent
a76d1d1c04
commit
66f2aab9af
6 changed files with 146 additions and 75 deletions
|
@ -36,8 +36,17 @@ message RemoveFileSinkResponse {
|
||||||
bool SinkGotRemoved = 1;
|
bool SinkGotRemoved = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ListSinksRequest {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListSinksResponse {
|
||||||
|
repeated string sinks = 1;
|
||||||
|
}
|
||||||
|
|
||||||
service Audit {
|
service Audit {
|
||||||
rpc WatchEvents (WatchEventsRequest) returns (stream inetmock.audit.EventEntity);
|
rpc WatchEvents (WatchEventsRequest) returns (stream inetmock.audit.EventEntity);
|
||||||
rpc RegisterFileSink (RegisterFileSinkRequest) returns (RegisterFileSinkResponse);
|
rpc RegisterFileSink (RegisterFileSinkRequest) returns (RegisterFileSinkResponse);
|
||||||
rpc RemoveFileSink (RemoveFileSinkRequest) returns (RemoveFileSinkResponse);
|
rpc RemoveFileSink (RemoveFileSinkRequest) returns (RemoveFileSinkResponse);
|
||||||
|
rpc ListSinks(ListSinksRequest) returns (ListSinksResponse);
|
||||||
}
|
}
|
|
@ -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
118
cmd/imctl/audit_sinks.go
Normal 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
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type printableEndpoint struct {
|
type printableEndpoint struct {
|
||||||
Id string
|
ID string
|
||||||
Name string
|
Name string
|
||||||
Handler string
|
Handler string
|
||||||
ListenAddress string
|
ListenAddress string
|
||||||
|
@ -34,7 +34,7 @@ type printableEndpoint struct {
|
||||||
|
|
||||||
func fromEndpoint(ep *rpc.Endpoint) *printableEndpoint {
|
func fromEndpoint(ep *rpc.Endpoint) *printableEndpoint {
|
||||||
return &printableEndpoint{
|
return &printableEndpoint{
|
||||||
Id: ep.Id,
|
ID: ep.Id,
|
||||||
Name: ep.Name,
|
Name: ep.Name,
|
||||||
Handler: ep.Handler,
|
Handler: ep.Handler,
|
||||||
ListenAddress: ep.ListenAddress,
|
ListenAddress: ep.ListenAddress,
|
||||||
|
|
|
@ -2,6 +2,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -20,7 +22,6 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
endpointsCmd.AddCommand(getEndpoints)
|
endpointsCmd.AddCommand(getEndpoints)
|
||||||
handlerCmd.AddCommand(getHandlersCmd)
|
handlerCmd.AddCommand(getHandlersCmd)
|
||||||
healthCmd.AddCommand(generalHealthCmd, containerHealthCmd)
|
healthCmd.AddCommand(generalHealthCmd, containerHealthCmd)
|
||||||
|
@ -29,7 +30,8 @@ func main() {
|
||||||
WithCommands(endpointsCmd, handlerCmd, healthCmd, auditCmd).
|
WithCommands(endpointsCmd, handlerCmd, healthCmd, auditCmd).
|
||||||
WithInitTasks(func(_ *cobra.Command, _ []string) (err error) {
|
WithInitTasks(func(_ *cobra.Command, _ []string) (err error) {
|
||||||
return initGRPCConnection()
|
return initGRPCConnection()
|
||||||
})
|
}).
|
||||||
|
WithLogger()
|
||||||
|
|
||||||
cliApp.RootCommand().PersistentFlags().StringVar(&inetMockSocketPath, "socket-path", "unix:///var/run/inetmock.sock", "Path to the INetMock socket file")
|
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")
|
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()
|
currentUser = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
watchEventsCmd.PersistentFlags().StringVar(
|
hostname := "."
|
||||||
&listenerName,
|
if hn, err := os.Hostname(); err == nil {
|
||||||
"listener-name",
|
hostname = hn
|
||||||
currentUser,
|
}
|
||||||
"set listener name - defaults to the current username, if the user cannot be determined a random UUID will be used",
|
|
||||||
)
|
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(watchEventsCmd, addFileCmd, removeFileCmd)
|
auditCmd.AddCommand(listSinksCmd, watchEventsCmd, addFileCmd, removeFileCmd, readFileCmd)
|
||||||
|
|
||||||
cliApp.MustRun()
|
cliApp.MustRun()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initGRPCConnection() (err error) {
|
func initGRPCConnection() (err error) {
|
||||||
|
|
|
@ -17,6 +17,12 @@ type auditServer struct {
|
||||||
eventStream audit.EventStream
|
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) {
|
func (a *auditServer) WatchEvents(req *WatchEventsRequest, srv Audit_WatchEventsServer) (err error) {
|
||||||
a.logger.Info("watcher attached", zap.String("name", req.WatcherName))
|
a.logger.Info("watcher attached", zap.String("name", req.WatcherName))
|
||||||
err = a.eventStream.RegisterSink(sink.NewGRPCSink(srv.Context(), req.WatcherName, func(ev audit.Event) {
|
err = a.eventStream.RegisterSink(sink.NewGRPCSink(srv.Context(), req.WatcherName, func(ev audit.Event) {
|
||||||
|
|
Loading…
Reference in a new issue