Merged CLI and server app init
This commit is contained in:
parent
37c87adaf3
commit
0138b57782
11 changed files with 302 additions and 165 deletions
|
@ -9,12 +9,19 @@ import 'pkg/audit/event_entity.proto';
|
||||||
|
|
||||||
package inetmock.rpc;
|
package inetmock.rpc;
|
||||||
|
|
||||||
|
enum FileOpenMode {
|
||||||
|
TRUNCATE = 0;
|
||||||
|
APPEND = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message WatchEventsRequest {
|
message WatchEventsRequest {
|
||||||
string watcherName = 1;
|
string watcherName = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RegisterFileSinkRequest {
|
message RegisterFileSinkRequest {
|
||||||
string targetPath = 1;
|
string targetPath = 1;
|
||||||
|
FileOpenMode openMode = 2;
|
||||||
|
uint32 permissions = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RegisterFileSinkResponse {
|
message RegisterFileSinkResponse {
|
||||||
|
|
|
@ -24,6 +24,13 @@ var (
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: runRemoveFile,
|
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) {
|
func runAddFile(_ *cobra.Command, args []string) (err error) {
|
||||||
|
@ -35,7 +42,7 @@ func runAddFile(_ *cobra.Command, args []string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auditClient := rpc.NewAuditClient(conn)
|
auditClient := rpc.NewAuditClient(conn)
|
||||||
ctx, cancel := context.WithTimeout(appCtx, grpcTimeout)
|
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
_, err = auditClient.RegisterFileSink(ctx, &rpc.RegisterFileSinkRequest{TargetPath: args[0]})
|
_, err = auditClient.RegisterFileSink(ctx, &rpc.RegisterFileSinkRequest{TargetPath: args[0]})
|
||||||
|
@ -44,9 +51,13 @@ func runAddFile(_ *cobra.Command, args []string) (err error) {
|
||||||
|
|
||||||
func runRemoveFile(_ *cobra.Command, args []string) (err error) {
|
func runRemoveFile(_ *cobra.Command, args []string) (err error) {
|
||||||
auditClient := rpc.NewAuditClient(conn)
|
auditClient := rpc.NewAuditClient(conn)
|
||||||
ctx, cancel := context.WithTimeout(appCtx, grpcTimeout)
|
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
_, err = auditClient.RemoveFileSink(ctx, &rpc.RemoveFileSinkRequest{TargetPath: args[0]})
|
_, err = auditClient.RemoveFileSink(ctx, &rpc.RemoveFileSinkRequest{TargetPath: args[0]})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runReadFile(_ *cobra.Command, args []string) (err error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ func watchAuditEvents(_ *cobra.Command, _ []string) (err error) {
|
||||||
auditClient := rpc.NewAuditClient(conn)
|
auditClient := rpc.NewAuditClient(conn)
|
||||||
|
|
||||||
var watchClient rpc.Audit_WatchEventsClient
|
var watchClient rpc.Audit_WatchEventsClient
|
||||||
if watchClient, err = auditClient.WatchEvents(appCtx, &rpc.WatchEventsRequest{WatcherName: listenerName}); err != nil {
|
if watchClient, err = auditClient.WatchEvents(cliApp.Context(), &rpc.WatchEventsRequest{WatcherName: listenerName}); err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func watchAuditEvents(_ *cobra.Command, _ []string) (err error) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
<-appCtx.Done()
|
<-cliApp.Context().Done()
|
||||||
err = watchClient.CloseSend()
|
err = watchClient.CloseSend()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"os/user"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
cliCmd = &cobra.Command{
|
|
||||||
Use: "",
|
|
||||||
Short: "IMCTL is the CLI app to interact with an INetMock server",
|
|
||||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
return initGRPCConnection()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
inetMockSocketPath string
|
|
||||||
outputFormat string
|
|
||||||
grpcTimeout time.Duration
|
|
||||||
appCtx context.Context
|
|
||||||
appCancel context.CancelFunc
|
|
||||||
conn *grpc.ClientConn
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
cliCmd.PersistentFlags().StringVar(&inetMockSocketPath, "socket-path", "unix:///var/run/inetmock.sock", "Path to the INetMock socket file")
|
|
||||||
cliCmd.PersistentFlags().StringVarP(&outputFormat, "format", "f", "table", "Output format to use. Possible values: table, json, yaml")
|
|
||||||
cliCmd.PersistentFlags().DurationVar(&grpcTimeout, "grpc-timeout", 5*time.Second, "Timeout to connect to the gRPC API")
|
|
||||||
|
|
||||||
cliCmd.AddCommand(endpointsCmd, handlerCmd, healthCmd, auditCmd)
|
|
||||||
endpointsCmd.AddCommand(getEndpoints)
|
|
||||||
handlerCmd.AddCommand(getHandlersCmd)
|
|
||||||
healthCmd.AddCommand(generalHealthCmd, containerHealthCmd)
|
|
||||||
|
|
||||||
currentUser := ""
|
|
||||||
if usr, err := user.Current(); err == nil {
|
|
||||||
currentUser = usr.Username
|
|
||||||
} else {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
func initGRPCConnection() (err error) {
|
|
||||||
appCtx, appCancel = context.WithCancel(context.Background())
|
|
||||||
|
|
||||||
signals := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
<-signals
|
|
||||||
appCancel()
|
|
||||||
}()
|
|
||||||
|
|
||||||
dialCtx, cancel := context.WithTimeout(appCtx, grpcTimeout)
|
|
||||||
conn, err = grpc.DialContext(dialCtx, inetMockSocketPath, grpc.WithInsecure())
|
|
||||||
cancel()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -51,7 +51,7 @@ func fromEndpoints(eps []*rpc.Endpoint) (out []*printableEndpoint) {
|
||||||
|
|
||||||
func runGetEndpoints(_ *cobra.Command, _ []string) (err error) {
|
func runGetEndpoints(_ *cobra.Command, _ []string) (err error) {
|
||||||
endpointsClient := rpc.NewEndpointsClient(conn)
|
endpointsClient := rpc.NewEndpointsClient(conn)
|
||||||
ctx, cancel := context.WithTimeout(appCtx, grpcTimeout)
|
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var endpointsResp *rpc.GetEndpointsResponse
|
var endpointsResp *rpc.GetEndpointsResponse
|
||||||
if endpointsResp, err = endpointsClient.GetEndpoints(ctx, &rpc.GetEndpointsRequest{}); err != nil {
|
if endpointsResp, err = endpointsClient.GetEndpoints(ctx, &rpc.GetEndpointsRequest{}); err != nil {
|
||||||
|
|
|
@ -40,7 +40,7 @@ func fromHandlers(hs []string) (handlers []*printableHandler) {
|
||||||
func runGetHandlers(_ *cobra.Command, _ []string) {
|
func runGetHandlers(_ *cobra.Command, _ []string) {
|
||||||
handlersClient := rpc.NewHandlersClient(conn)
|
handlersClient := rpc.NewHandlersClient(conn)
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(appCtx, grpcTimeout)
|
ctx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var err error
|
var err error
|
||||||
var handlersResp *rpc.GetHandlersResponse
|
var handlersResp *rpc.GetHandlersResponse
|
||||||
|
|
|
@ -1,8 +1,63 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os/user"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"gitlab.com/inetmock/inetmock/internal/app"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
inetMockSocketPath string
|
||||||
|
outputFormat string
|
||||||
|
grpcTimeout time.Duration
|
||||||
|
cliApp app.App
|
||||||
|
conn *grpc.ClientConn
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
defer appCancel()
|
|
||||||
if err := cliCmd.Execute(); err != nil {
|
endpointsCmd.AddCommand(getEndpoints)
|
||||||
panic(err)
|
handlerCmd.AddCommand(getHandlersCmd)
|
||||||
|
healthCmd.AddCommand(generalHealthCmd, containerHealthCmd)
|
||||||
|
|
||||||
|
cliApp = app.NewApp("imctl", "IMCTL is the CLI app to interact with an INetMock server").
|
||||||
|
WithCommands(endpointsCmd, handlerCmd, healthCmd, auditCmd).
|
||||||
|
WithInitTasks(func(_ *cobra.Command, _ []string) (err error) {
|
||||||
|
return initGRPCConnection()
|
||||||
|
})
|
||||||
|
|
||||||
|
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().DurationVar(&grpcTimeout, "grpc-timeout", 5*time.Second, "Timeout to connect to the gRPC API")
|
||||||
|
|
||||||
|
currentUser := ""
|
||||||
|
if usr, err := user.Current(); err == nil {
|
||||||
|
currentUser = usr.Username
|
||||||
|
} else {
|
||||||
|
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)
|
||||||
|
|
||||||
|
cliApp.MustRun()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func initGRPCConnection() (err error) {
|
||||||
|
dialCtx, cancel := context.WithTimeout(cliApp.Context(), grpcTimeout)
|
||||||
|
conn, err = grpc.DialContext(dialCtx, inetMockSocketPath, grpc.WithInsecure())
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,13 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
"gitlab.com/inetmock/inetmock/internal/app"
|
"gitlab.com/inetmock/inetmock/internal/app"
|
||||||
"gitlab.com/inetmock/inetmock/internal/endpoint/handler/dns/mock"
|
dns "gitlab.com/inetmock/inetmock/internal/endpoint/handler/dns/mock"
|
||||||
_ "gitlab.com/inetmock/inetmock/internal/endpoint/handler/dns/mock"
|
http "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http/mock"
|
||||||
_ "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http/mock"
|
|
||||||
mock2 "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http/mock"
|
|
||||||
"gitlab.com/inetmock/inetmock/internal/endpoint/handler/http/proxy"
|
"gitlab.com/inetmock/inetmock/internal/endpoint/handler/http/proxy"
|
||||||
_ "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http/proxy"
|
|
||||||
"gitlab.com/inetmock/inetmock/internal/endpoint/handler/metrics"
|
"gitlab.com/inetmock/inetmock/internal/endpoint/handler/metrics"
|
||||||
_ "gitlab.com/inetmock/inetmock/internal/endpoint/handler/metrics"
|
|
||||||
"gitlab.com/inetmock/inetmock/internal/endpoint/handler/tls/interceptor"
|
"gitlab.com/inetmock/inetmock/internal/endpoint/handler/tls/interceptor"
|
||||||
_ "gitlab.com/inetmock/inetmock/internal/endpoint/handler/tls/interceptor"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,18 +24,19 @@ func main() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var err error
|
app.NewApp("inetmock", "INetMock is lightweight internet mock").
|
||||||
if server, err = app.NewApp(
|
WithHandlerRegistry(
|
||||||
mock2.AddHTTPMock,
|
http.AddHTTPMock,
|
||||||
mock.AddDNSMock,
|
dns.AddDNSMock,
|
||||||
interceptor.AddTLSInterceptor,
|
interceptor.AddTLSInterceptor,
|
||||||
proxy.AddHTTPProxy,
|
proxy.AddHTTPProxy,
|
||||||
metrics.AddMetricsExporter,
|
metrics.AddMetricsExporter).
|
||||||
); err != nil {
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
server.
|
|
||||||
WithCommands(serveCmd, generateCaCmd).
|
WithCommands(serveCmd, generateCaCmd).
|
||||||
|
WithConfig().
|
||||||
|
WithLogger().
|
||||||
|
WithHealthChecker().
|
||||||
|
WithCertStore().
|
||||||
|
WithEventStream().
|
||||||
|
WithEndpointManager().
|
||||||
MustRun()
|
MustRun()
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -14,6 +14,7 @@ require (
|
||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/spf13/viper v1.7.1
|
github.com/spf13/viper v1.7.1
|
||||||
|
go.uber.org/multierr v1.5.0
|
||||||
go.uber.org/zap v1.16.0
|
go.uber.org/zap v1.16.0
|
||||||
google.golang.org/grpc v1.34.0
|
google.golang.org/grpc v1.34.0
|
||||||
google.golang.org/protobuf v1.25.0
|
google.golang.org/protobuf v1.25.0
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"gitlab.com/inetmock/inetmock/pkg/health"
|
"gitlab.com/inetmock/inetmock/pkg/health"
|
||||||
"gitlab.com/inetmock/inetmock/pkg/logging"
|
"gitlab.com/inetmock/inetmock/pkg/logging"
|
||||||
"gitlab.com/inetmock/inetmock/pkg/path"
|
"gitlab.com/inetmock/inetmock/pkg/path"
|
||||||
|
"go.uber.org/multierr"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -27,6 +28,18 @@ var (
|
||||||
developmentLogs bool
|
developmentLogs bool
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type contextKey string
|
||||||
|
|
||||||
|
const (
|
||||||
|
loggerKey contextKey = "gitlab.com/inetmock/inetmock/app/context/logger"
|
||||||
|
configKey contextKey = "gitlab.com/inetmock/inetmock/app/context/config"
|
||||||
|
handlerRegistryKey contextKey = "gitlab.com/inetmock/inetmock/app/context/handlerRegistry"
|
||||||
|
healthCheckerKey contextKey = "gitlab.com/inetmock/inetmock/app/context/healthChecker"
|
||||||
|
endpointManagerKey contextKey = "gitlab.com/inetmock/inetmock/app/context/endpointManager"
|
||||||
|
certStoreKey contextKey = "gitlab.com/inetmock/inetmock/app/context/certStore"
|
||||||
|
eventStreamKey contextKey = "gitlab.com/inetmock/inetmock/app/context/eventStream"
|
||||||
|
)
|
||||||
|
|
||||||
type App interface {
|
type App interface {
|
||||||
api.PluginContext
|
api.PluginContext
|
||||||
EventStream() audit.EventStream
|
EventStream() audit.EventStream
|
||||||
|
@ -35,28 +48,56 @@ type App interface {
|
||||||
EndpointManager() endpoint.EndpointManager
|
EndpointManager() endpoint.EndpointManager
|
||||||
HandlerRegistry() api.HandlerRegistry
|
HandlerRegistry() api.HandlerRegistry
|
||||||
Context() context.Context
|
Context() context.Context
|
||||||
|
RootCommand() *cobra.Command
|
||||||
MustRun()
|
MustRun()
|
||||||
Shutdown()
|
Shutdown()
|
||||||
|
|
||||||
|
// WithCommands adds subcommands to the root command
|
||||||
|
// requires nothing
|
||||||
WithCommands(cmds ...*cobra.Command) App
|
WithCommands(cmds ...*cobra.Command) App
|
||||||
|
|
||||||
|
// WithHandlerRegistry builds up the handler registry
|
||||||
|
// requires nothing
|
||||||
|
WithHandlerRegistry(registrations ...api.Registration) App
|
||||||
|
|
||||||
|
// WithHealthChecker adds the health checker mechanism
|
||||||
|
// requires nothing
|
||||||
|
WithHealthChecker() App
|
||||||
|
|
||||||
|
// WithLogger configures the logging system
|
||||||
|
// requires nothing
|
||||||
|
WithLogger() App
|
||||||
|
|
||||||
|
// WithEndpointManager creates an endpoint manager instance and adds it to the context
|
||||||
|
// requires WithHandlerRegistry, WithHealthChecker and WithLogger
|
||||||
|
WithEndpointManager() App
|
||||||
|
|
||||||
|
// WithCertStore initializes the cert store
|
||||||
|
// requires WithLogger and WithConfig
|
||||||
|
WithCertStore() App
|
||||||
|
|
||||||
|
// WithEventStream adds the audit event stream
|
||||||
|
// requires WithLogger
|
||||||
|
WithEventStream() App
|
||||||
|
|
||||||
|
// WithConfig loads the config
|
||||||
|
// requires nothing
|
||||||
|
WithConfig() App
|
||||||
|
|
||||||
|
WithInitTasks(task ...func(cmd *cobra.Command, args []string) (err error)) App
|
||||||
}
|
}
|
||||||
|
|
||||||
type app struct {
|
type app struct {
|
||||||
cfg config.Config
|
|
||||||
rootCmd *cobra.Command
|
rootCmd *cobra.Command
|
||||||
rootLogger logging.Logger
|
|
||||||
certStore cert.Store
|
|
||||||
checker health.Checker
|
|
||||||
endpointManager endpoint.EndpointManager
|
|
||||||
registry api.HandlerRegistry
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
eventStream audit.EventStream
|
lateInitTasks []func(cmd *cobra.Command, args []string) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *app) MustRun() {
|
func (a *app) MustRun() {
|
||||||
if err := a.rootCmd.Execute(); err != nil {
|
if err := a.rootCmd.Execute(); err != nil {
|
||||||
if a.rootLogger != nil {
|
if a.Logger() != nil {
|
||||||
a.rootLogger.Error(
|
a.Logger().Error(
|
||||||
"Failed to run inetmock",
|
"Failed to run inetmock",
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
|
@ -66,68 +107,191 @@ func (a *app) MustRun() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) Logger() logging.Logger {
|
func (a *app) Logger() logging.Logger {
|
||||||
return a.rootLogger
|
return a.ctx.Value(loggerKey).(logging.Logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) Config() config.Config {
|
func (a *app) Config() config.Config {
|
||||||
return a.cfg
|
return a.ctx.Value(configKey).(config.Config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) CertStore() cert.Store {
|
func (a *app) CertStore() cert.Store {
|
||||||
return a.certStore
|
return a.ctx.Value(certStoreKey).(cert.Store)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) Checker() health.Checker {
|
func (a *app) Checker() health.Checker {
|
||||||
return a.checker
|
return a.ctx.Value(healthCheckerKey).(health.Checker)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) EndpointManager() endpoint.EndpointManager {
|
func (a *app) EndpointManager() endpoint.EndpointManager {
|
||||||
return a.endpointManager
|
return a.ctx.Value(endpointManagerKey).(endpoint.EndpointManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) Audit() audit.Emitter {
|
func (a *app) Audit() audit.Emitter {
|
||||||
return a.eventStream
|
return a.ctx.Value(eventStreamKey).(audit.Emitter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) EventStream() audit.EventStream {
|
func (a *app) EventStream() audit.EventStream {
|
||||||
return a.eventStream
|
return a.ctx.Value(eventStreamKey).(audit.EventStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) HandlerRegistry() api.HandlerRegistry {
|
func (a *app) HandlerRegistry() api.HandlerRegistry {
|
||||||
return a.registry
|
return a.ctx.Value(handlerRegistryKey).(api.HandlerRegistry)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) Context() context.Context {
|
func (a *app) Context() context.Context {
|
||||||
return a.ctx
|
return a.ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a app) Shutdown() {
|
func (a *app) RootCommand() *cobra.Command {
|
||||||
|
return a.rootCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) Shutdown() {
|
||||||
a.cancel()
|
a.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithCommands adds subcommands to the root command
|
||||||
|
// requires nothing
|
||||||
func (a *app) WithCommands(cmds ...*cobra.Command) App {
|
func (a *app) WithCommands(cmds ...*cobra.Command) App {
|
||||||
a.rootCmd.AddCommand(cmds...)
|
a.rootCmd.AddCommand(cmds...)
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApp(registrations ...api.Registration) (inetmockApp App, err error) {
|
// WithHandlerRegistry builds up the handler registry
|
||||||
|
// requires nothing
|
||||||
|
func (a *app) WithHandlerRegistry(registrations ...api.Registration) App {
|
||||||
registry := api.NewHandlerRegistry()
|
registry := api.NewHandlerRegistry()
|
||||||
|
|
||||||
for _, registration := range registrations {
|
for _, registration := range registrations {
|
||||||
if err = registration(registry); err != nil {
|
if err := registration(registry); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.ctx = context.WithValue(a.ctx, handlerRegistryKey, registry)
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithHealthChecker adds the health checker mechanism
|
||||||
|
// requires nothing
|
||||||
|
func (a *app) WithHealthChecker() App {
|
||||||
|
checker := health.New()
|
||||||
|
a.ctx = context.WithValue(a.ctx, healthCheckerKey, checker)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLogger configures the logging system
|
||||||
|
// requires nothing
|
||||||
|
func (a *app) WithLogger() App {
|
||||||
|
a.lateInitTasks = append(a.lateInitTasks, func(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
logging.ConfigureLogging(
|
||||||
|
logging.ParseLevel(logLevel),
|
||||||
|
developmentLogs,
|
||||||
|
map[string]interface{}{
|
||||||
|
"cwd": path.WorkingDirectory(),
|
||||||
|
"cmd": cmd.Name(),
|
||||||
|
"args": args,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
var logger logging.Logger
|
||||||
|
if logger, err = logging.CreateLogger(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
a.ctx = context.WithValue(a.ctx, loggerKey, logger)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithEndpointManager creates an endpoint manager instance and adds it to the context
|
||||||
|
// requires WithHandlerRegistry, WithHealthChecker and WithLogger
|
||||||
|
func (a *app) WithEndpointManager() App {
|
||||||
|
a.lateInitTasks = append(a.lateInitTasks, func(_ *cobra.Command, _ []string) (err error) {
|
||||||
|
epMgr := endpoint.NewEndpointManager(
|
||||||
|
a.HandlerRegistry(),
|
||||||
|
a.Logger().Named("EndpointManager"),
|
||||||
|
a.Checker(),
|
||||||
|
a,
|
||||||
|
)
|
||||||
|
|
||||||
|
a.ctx = context.WithValue(a.ctx, endpointManagerKey, epMgr)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCertStore initializes the cert store
|
||||||
|
// requires WithLogger and WithConfig
|
||||||
|
func (a *app) WithCertStore() App {
|
||||||
|
a.lateInitTasks = append(a.lateInitTasks, func(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
var certStore cert.Store
|
||||||
|
if certStore, err = cert.NewDefaultStore(
|
||||||
|
a.Config(),
|
||||||
|
a.Logger().Named("CertStore"),
|
||||||
|
); err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := initAppContext()
|
a.ctx = context.WithValue(a.ctx, certStoreKey, certStore)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithEventStream adds the audit event stream
|
||||||
|
// requires WithLogger
|
||||||
|
func (a *app) WithEventStream() App {
|
||||||
|
a.lateInitTasks = append(a.lateInitTasks, func(_ *cobra.Command, _ []string) (err error) {
|
||||||
|
var eventStream audit.EventStream
|
||||||
|
eventStream, err = audit.NewEventStream(
|
||||||
|
a.Logger().Named("EventStream"),
|
||||||
|
audit.WithSinkBufferSize(10),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = eventStream.RegisterSink(sink.NewLogSink(a.Logger().Named("LogSink"))); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
a.ctx = context.WithValue(a.ctx, eventStreamKey, eventStream)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithConfig loads the config
|
||||||
|
// requires nothing
|
||||||
|
func (a *app) WithConfig() App {
|
||||||
|
a.lateInitTasks = append(a.lateInitTasks, func(cmd *cobra.Command, _ []string) (err error) {
|
||||||
|
cfg := config.CreateConfig(cmd.Flags())
|
||||||
|
if err = cfg.ReadConfig(configFilePath); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a.ctx = context.WithValue(a.ctx, configKey, cfg)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) WithInitTasks(task ...func(cmd *cobra.Command, args []string) (err error)) App {
|
||||||
|
a.lateInitTasks = append(a.lateInitTasks, task...)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApp(name, short string) App {
|
||||||
|
ctx, cancel := initAppContext()
|
||||||
a := &app{
|
a := &app{
|
||||||
rootCmd: &cobra.Command{
|
rootCmd: &cobra.Command{
|
||||||
Short: "INetMock is lightweight internet mock",
|
Use: name,
|
||||||
|
Short: short,
|
||||||
},
|
},
|
||||||
checker: health.New(),
|
|
||||||
registry: registry,
|
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
}
|
}
|
||||||
|
@ -137,48 +301,13 @@ func NewApp(registrations ...api.Registration) (inetmockApp App, err error) {
|
||||||
a.rootCmd.PersistentFlags().BoolVar(&developmentLogs, "development-logs", false, "Enable development mode logs")
|
a.rootCmd.PersistentFlags().BoolVar(&developmentLogs, "development-logs", false, "Enable development mode logs")
|
||||||
|
|
||||||
a.rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) (err error) {
|
a.rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) (err error) {
|
||||||
logging.ConfigureLogging(
|
for _, initTask := range a.lateInitTasks {
|
||||||
logging.ParseLevel(logLevel),
|
err = multierr.Append(err, initTask(cmd, args))
|
||||||
developmentLogs,
|
}
|
||||||
map[string]interface{}{
|
|
||||||
"cwd": path.WorkingDirectory(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if a.rootLogger, err = logging.CreateLogger(); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a.endpointManager = endpoint.NewEndpointManager(
|
return a
|
||||||
a.registry,
|
|
||||||
a.Logger().Named("EndpointManager"),
|
|
||||||
a.checker,
|
|
||||||
a,
|
|
||||||
)
|
|
||||||
|
|
||||||
a.cfg = config.CreateConfig(cmd.Flags())
|
|
||||||
|
|
||||||
if err = a.cfg.ReadConfig(configFilePath); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.certStore, err = cert.NewDefaultStore(a.cfg, a.rootLogger); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
a.eventStream, err = audit.NewEventStream(
|
|
||||||
a.Logger().Named("EventStream"),
|
|
||||||
audit.WithSinkBufferSize(10),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = a.eventStream.RegisterSink(sink.NewLogSink(a.Logger().Named("LogSink")))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return a, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initAppContext() (context.Context, context.CancelFunc) {
|
func initAppContext() (context.Context, context.CancelFunc) {
|
||||||
|
|
|
@ -36,7 +36,21 @@ func (a *auditServer) WatchEvents(req *WatchEventsRequest, srv Audit_WatchEvents
|
||||||
|
|
||||||
func (a *auditServer) RegisterFileSink(_ context.Context, req *RegisterFileSinkRequest) (resp *RegisterFileSinkResponse, err error) {
|
func (a *auditServer) RegisterFileSink(_ context.Context, req *RegisterFileSinkRequest) (resp *RegisterFileSinkResponse, err error) {
|
||||||
var writer io.WriteCloser
|
var writer io.WriteCloser
|
||||||
if writer, err = os.OpenFile(req.TargetPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644); err != nil {
|
var flags int
|
||||||
|
|
||||||
|
switch req.OpenMode {
|
||||||
|
case FileOpenMode_APPEND:
|
||||||
|
flags = os.O_CREATE | os.O_WRONLY | os.O_APPEND
|
||||||
|
default:
|
||||||
|
flags = os.O_CREATE | os.O_WRONLY | os.O_TRUNC
|
||||||
|
}
|
||||||
|
|
||||||
|
var permissions = os.FileMode(req.Permissions)
|
||||||
|
if permissions == 0 {
|
||||||
|
permissions = 644
|
||||||
|
}
|
||||||
|
|
||||||
|
if writer, err = os.OpenFile(req.TargetPath, flags, permissions); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = a.eventStream.RegisterSink(sink.NewWriterSink(req.TargetPath, audit.NewEventWriter(writer))); err != nil {
|
if err = a.eventStream.RegisterSink(sink.NewWriterSink(req.TargetPath, audit.NewEventWriter(writer))); err != nil {
|
||||||
|
|
Loading…
Reference in a new issue