From 6a171c0f23e2cb328119374c6eecd36cf99c8dfc Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Fri, 1 Sep 2023 15:56:17 +0100 Subject: [PATCH 01/20] WIP: move code about --- main.go | 148 ++---------------- sdk/agent/events/meta.go | 96 ++++++++++++ sdk/agent/events/meta_test.go | 79 ++++++++++ sdk/agent/events/types.go | 19 +++ src/core/config/config.go | 16 ++ src/core/config/defaults.go | 2 + src/core/grpc.go | 75 +++++++++ src/core/grpc_test.go | 56 +++++++ src/core/pipe.go | 9 ++ src/core/signals.go | 74 +++++++++ src/plugins/events.go | 131 +++------------- src/plugins/events_test.go | 18 ++- .../nginx/agent/sdk/v2/agent/events/meta.go | 96 ++++++++++++ .../nginx/agent/sdk/v2/agent/events/types.go | 19 +++ .../nginx/agent/v2/src/core/config/config.go | 16 ++ .../agent/v2/src/core/config/defaults.go | 2 + .../nginx/agent/v2/src/core/grpc.go | 75 +++++++++ .../nginx/agent/v2/src/core/pipe.go | 9 ++ .../nginx/agent/v2/src/core/signals.go | 74 +++++++++ test/integration/vendor/modules.txt | 1 + test/performance/plugins_test.go | 58 +++++++ .../nginx/agent/sdk/v2/agent/events/meta.go | 96 ++++++++++++ .../nginx/agent/sdk/v2/agent/events/types.go | 19 +++ .../nginx/agent/v2/src/core/config/config.go | 16 ++ .../agent/v2/src/core/config/defaults.go | 2 + .../nginx/agent/v2/src/core/grpc.go | 75 +++++++++ .../nginx/agent/v2/src/core/pipe.go | 9 ++ .../nginx/agent/v2/src/core/signals.go | 74 +++++++++ .../nginx/agent/v2/src/plugins/events.go | 131 +++------------- test/performance/vendor/modules.txt | 1 + .../nginx/agent/sdk/v2/agent/events/meta.go | 96 ++++++++++++ .../nginx/agent/sdk/v2/agent/events/types.go | 19 +++ vendor/modules.txt | 1 + 33 files changed, 1265 insertions(+), 347 deletions(-) create mode 100644 sdk/agent/events/meta.go create mode 100644 sdk/agent/events/meta_test.go create mode 100644 sdk/agent/events/types.go create mode 100644 src/core/grpc.go create mode 100644 src/core/grpc_test.go create mode 100644 src/core/signals.go create mode 100644 test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go create mode 100644 test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go create mode 100644 test/integration/vendor/github.com/nginx/agent/v2/src/core/grpc.go create mode 100644 test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go create mode 100644 test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go create mode 100644 test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go create mode 100644 test/performance/vendor/github.com/nginx/agent/v2/src/core/grpc.go create mode 100644 test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go create mode 100644 vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go create mode 100644 vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go diff --git a/main.go b/main.go index aedae9f34..a4723bdeb 100644 --- a/main.go +++ b/main.go @@ -10,14 +10,10 @@ package main import ( "context" "os" - "os/signal" - "runtime" "strconv" - "strings" - "syscall" - "time" agent_config "github.com/nginx/agent/sdk/v2/agent/config" + "github.com/nginx/agent/sdk/v2/agent/events" "github.com/nginx/agent/sdk/v2/client" sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" "github.com/nginx/agent/v2/src/core" @@ -29,7 +25,6 @@ import ( "github.com/google/uuid" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "google.golang.org/grpc" ) var ( @@ -39,19 +34,7 @@ var ( ) func init() { - config.SetVersion(version, commit) - config.SetDefaults() - config.RegisterFlags() - dynamicConfigPath := config.DynamicConfigFileAbsPath - if runtime.GOOS == "freebsd" { - dynamicConfigPath = config.DynamicConfigFileAbsFreeBsdPath - } - configPath, err := config.RegisterConfigFile(dynamicConfigPath, config.ConfigFileName, config.ConfigFilePaths()...) - if err != nil { - log.Fatalf("Failed to load configuration file: %v", err) - } - log.Debugf("Configuration file loaded %v", configPath) - config.Viper.Set(config.ConfigPathKey, configPath) + config.InitConfiguration(version, commit) } func main() { @@ -83,7 +66,7 @@ func main() { version, commit, os.Getpid(), loadedConfig.ClientID, loadedConfig.DisplayName, loadedConfig.Features) sdkGRPC.InitMeta(loadedConfig.ClientID, loadedConfig.CloudAccountID) - controller, commander, reporter := createGrpcClients(ctx, loadedConfig) + controller, commander, reporter := core.CreateGrpcClients(ctx, loadedConfig) if controller != nil { if err := controller.Connect(); err != nil { @@ -96,13 +79,19 @@ func main() { corePlugins, extensionPlugins := loadPlugins(commander, binary, env, reporter, loadedConfig) - pipe := initializeMessagePipe(ctx, corePlugins, extensionPlugins) + pipe := core.InitializePipe(ctx, corePlugins, extensionPlugins, agent_config.DefaultPluginSize) - pipe.Process(core.NewMessage(core.AgentStarted, - plugins.NewAgentEventMeta(version, strconv.Itoa(os.Getpid()))), - ) + event := events.NewAgentEventMeta(config.MODULE, + version, + strconv.Itoa(os.Getpid()), + "Initialize Agent", + env.GetHostname(), + env.GetSystemUUID(), + loadedConfig.InstanceGroup, + loadedConfig.Tags) - handleSignals(ctx, commander, loadedConfig, env, pipe, cancel, controller) + pipe.Process(core.NewMessage(core.AgentStarted, event)) + core.HandleSignals(ctx, commander, loadedConfig, env, pipe, cancel, controller) pipe.Run() }) @@ -112,99 +101,6 @@ func main() { } } -// handleSignals handles signals to attempt graceful shutdown -// for now it also handles sending the agent stopped event because as of today we don't have a mechanism for synchronizing -// tasks between multiple plugins from outside a plugin -func handleSignals( - ctx context.Context, - cmder client.Commander, - loadedConfig *config.Config, - env core.Environment, - pipe core.MessagePipeInterface, - cancel context.CancelFunc, - controller client.Controller, -) { - sigChan := make(chan os.Signal, 1) - signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) - go func() { - select { - case <-sigChan: - stopCmd := plugins.GenerateAgentStopEventCommand( - plugins.NewAgentEventMeta(version, strconv.Itoa(os.Getpid())), loadedConfig, env, - ) - log.Debugf("Sending agent stopped event: %v", stopCmd) - - if cmder == nil { - log.Warn("Command channel not configured. Skipping sending AgentStopped event") - } else if err := cmder.Send(ctx, client.MessageFromCommand(stopCmd)); err != nil { - log.Errorf("Error sending AgentStopped event to command channel: %v", err) - } - - if controller != nil { - if err := controller.Close(); err != nil { - log.Warnf("Unable to close controller: %v", err) - } - } - - log.Warn("NGINX Agent exiting") - cancel() - - timeout := time.Second * 5 - time.Sleep(timeout) - log.Fatalf("Failed to gracefully shutdown within timeout of %v. Exiting", timeout) - case <-ctx.Done(): - } - }() -} - -func createGrpcClients(ctx context.Context, loadedConfig *config.Config) (client.Controller, client.Commander, client.MetricReporter) { - if !loadedConfig.IsGrpcServerConfigured() { - log.Info("GRPC clients not created due to missing server config") - return nil, nil, nil - } - - grpcDialOptions := setDialOptions(loadedConfig) - secureMetricsDialOpts, err := sdkGRPC.SecureDialOptions( - loadedConfig.TLS.Enable, - loadedConfig.TLS.Cert, - loadedConfig.TLS.Key, - loadedConfig.TLS.Ca, - loadedConfig.Server.Metrics, - loadedConfig.TLS.SkipVerify) - if err != nil { - log.Fatalf("Failed to load secure metric gRPC dial options: %v", err) - } - - secureCmdDialOpts, err := sdkGRPC.SecureDialOptions( - loadedConfig.TLS.Enable, - loadedConfig.TLS.Cert, - loadedConfig.TLS.Key, - loadedConfig.TLS.Ca, - loadedConfig.Server.Command, - loadedConfig.TLS.SkipVerify) - if err != nil { - log.Fatalf("Failed to load secure command gRPC dial options: %v", err) - } - - controller := client.NewClientController() - controller.WithContext(ctx) - commander := client.NewCommanderClient() - commander.WithBackoffSettings(loadedConfig.GetServerBackoffSettings()) - - commander.WithServer(loadedConfig.Server.Target) - commander.WithDialOptions(append(grpcDialOptions, secureCmdDialOpts)...) - - reporter := client.NewMetricReporterClient() - reporter.WithBackoffSettings(loadedConfig.GetServerBackoffSettings()) - reporter.WithServer(loadedConfig.Server.Target) - reporter.WithDialOptions(append(grpcDialOptions, secureMetricsDialOpts)...) - - controller.WithClient(commander) - controller.WithClient(reporter) - - return controller, commander, reporter -} - func loadPlugins(commander client.Commander, binary *core.NginxBinaryType, env *core.EnvironmentType, reporter client.MetricReporter, loadedConfig *config.Config) ([]core.Plugin, []core.ExtensionPlugin) { var corePlugins []core.Plugin var extensionPlugins []core.ExtensionPlugin @@ -298,19 +194,3 @@ func loadPlugins(commander client.Commander, binary *core.NginxBinaryType, env * return corePlugins, extensionPlugins } - -func initializeMessagePipe(ctx context.Context, corePlugins []core.Plugin, extensionPlugins []core.ExtensionPlugin) core.MessagePipeInterface { - pipe := core.NewMessagePipe(ctx) - err := pipe.Register(agent_config.DefaultPluginSize, corePlugins, extensionPlugins) - if err != nil { - log.Warnf("Failed to start agent successfully, error loading plugins %v", err) - } - return pipe -} - -func setDialOptions(loadedConfig *config.Config) []grpc.DialOption { - grpcDialOptions := []grpc.DialOption{grpc.WithUserAgent("nginx-agent/" + strings.TrimPrefix(version, "v"))} - grpcDialOptions = append(grpcDialOptions, sdkGRPC.DefaultClientDialOptions...) - grpcDialOptions = append(grpcDialOptions, sdkGRPC.DataplaneConnectionDialOptions(loadedConfig.Server.Token, sdkGRPC.NewMessageMeta(uuid.NewString()))...) - return grpcDialOptions -} diff --git a/sdk/agent/events/meta.go b/sdk/agent/events/meta.go new file mode 100644 index 000000000..ca2885dff --- /dev/null +++ b/sdk/agent/events/meta.go @@ -0,0 +1,96 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package events + +import ( + "fmt" + "strings" + + "github.com/gogo/protobuf/types" + "github.com/google/uuid" + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/sdk/v2/proto" + commonProto "github.com/nginx/agent/sdk/v2/proto/common" + eventsProto "github.com/nginx/agent/sdk/v2/proto/events" +) + +type AgentEventMeta struct { + module string + version string + pid string + message string + hostname string + systemUuid string + instanceGroup string + tags []string +} + +func NewAgentEventMeta( + module, version, pid, message, hostname, systemUuid, instanceGroup string, + tags []string, +) *AgentEventMeta { + return &AgentEventMeta{ + module: module, + version: version, + pid: pid, + message: message, + hostname: hostname, + systemUuid: systemUuid, + instanceGroup: instanceGroup, + tags: tags, + } +} + +func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { + activityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf(agentEvent.message, agentEvent.version, agentEvent.pid, agentEvent.hostname), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: agentEvent.systemUuid, + }, + { + Name: "hostname", + Value: agentEvent.hostname, + }, + { + Name: "instance_group", + Value: agentEvent.instanceGroup, + }, + { + Name: "system.tags", + Value: strings.Join(agentEvent.tags, ","), + }, + }, + } + + event := &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: uuid.NewString(), + Module: agentEvent.module, + Timestamp: types.TimestampNow(), + EventLevel: WARN_EVENT_LEVEL, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } + + return &proto.Command{ + Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), + Type: proto.Command_NORMAL, + Data: &proto.Command_EventReport{ + EventReport: &eventsProto.EventReport{ + Events: []*eventsProto.Event{event}, + }, + }, + } +} diff --git a/sdk/agent/events/meta_test.go b/sdk/agent/events/meta_test.go new file mode 100644 index 000000000..9f0195078 --- /dev/null +++ b/sdk/agent/events/meta_test.go @@ -0,0 +1,79 @@ +package events + +import ( + "testing" + + "github.com/nginx/agent/sdk/v2/proto" + eventsProto "github.com/nginx/agent/sdk/v2/proto/events" + "github.com/stretchr/testify/assert" +) + +func TestNewAgentEventMeta(t *testing.T) { + // Create an instance of AgentEventMeta using the constructor + module := "nginx-agent" + version := "v1.0" + pid := "12345" + message := "Sample message: Version=%s, PID=%s, Hostname=%s" + hostname := "example-host" + systemUuid := "system-uuid" + instanceGroup := "group1" + tags := []string{"tag1", "tag2"} + + meta := NewAgentEventMeta(module, version, pid, message, hostname, systemUuid, instanceGroup, tags) + + assert.NotNil(t, meta) + + assert.Equal(t, version, meta.version) + assert.Equal(t, pid, meta.pid) + assert.Equal(t, message, meta.message) + assert.Equal(t, hostname, meta.hostname) + assert.Equal(t, systemUuid, meta.systemUuid) + assert.Equal(t, instanceGroup, meta.instanceGroup) + assert.Equal(t, tags, meta.tags) +} + +func TestGenerateAgentStopEventCommand(t *testing.T) { + // Create a mock AgentEventMeta object + agentEvent := &AgentEventMeta{ + module: "agent-module", + version: "v2.0", + pid: "54321", + message: "Sample message: Version=%s, PID=%s, Hostname=%s", + hostname: "test-host", + systemUuid: "test-uuid", + instanceGroup: "group2", + tags: []string{"tag3", "tag4"}, + } + + expected := &eventsProto.EventReport{ + Events: []*eventsProto.Event{ + { + Metadata: &eventsProto.Metadata{ + Module: agentEvent.module, + Type: AGENT_EVENT_TYPE, + Category: CONFIG_CATEGORY, + EventLevel: ERROR_EVENT_LEVEL, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: &eventsProto.ActivityEvent{ + Message: "failed to rollback nginx config on test-host", + Dimensions: nil, + }, + }, + }, + }, + } + + // Generate the AgentStopEventCommand using the function + cmd := GenerateAgentStopEventCommand(agentEvent) + + // Assert that the generated command is not nil + assert.NotNil(t, cmd) + + // You can add more specific assertions based on the expected structure and values of the generated command. + // For example, checking the UUIDs, message format, and other fields. + assert.NotNil(t, cmd.Meta) + assert.Equal(t, proto.Command_NORMAL, cmd.Type) + assert.NotNil(t, cmd.Data) + assert.Equal(t, expected, cmd.GetData()) +} diff --git a/sdk/agent/events/types.go b/sdk/agent/events/types.go new file mode 100644 index 000000000..0340d130d --- /dev/null +++ b/sdk/agent/events/types.go @@ -0,0 +1,19 @@ +package events + +const ( + // Types + NGINX_EVENT_TYPE = "Nginx" + AGENT_EVENT_TYPE = "Agent" + + // Categories + STATUS_CATEGORY = "Status" + CONFIG_CATEGORY = "Config" + APP_PROTECT_CATEGORY = "AppProtect" + + // Event Levels + INFO_EVENT_LEVEL = "INFO" + DEBUG_EVENT_LEVEL = "DEBUG" + WARN_EVENT_LEVEL = "WARN" + ERROR_EVENT_LEVEL = "ERROR" + CRITICAL_EVENT_LEVEL = "CRITICAL" +) diff --git a/src/core/config/config.go b/src/core/config/config.go index 638ebff64..4f6983717 100644 --- a/src/core/config/config.go +++ b/src/core/config/config.go @@ -62,6 +62,22 @@ func Execute() error { return ROOT_COMMAND.Execute() } +func InitConfiguration(version, commit string) { + SetVersion(version, commit) + SetDefaults() + RegisterFlags() + dynamicConfigPath := DynamicConfigFileAbsPath + if runtime.GOOS == "freebsd" { + dynamicConfigPath = DynamicConfigFileAbsFreeBsdPath + } + configPath, err := RegisterConfigFile(dynamicConfigPath, ConfigFileName, ConfigFilePaths()...) + if err != nil { + log.Fatalf("Failed to load configuration file: %v", err) + } + log.Debugf("Configuration file loaded %v", configPath) + Viper.Set(ConfigPathKey, configPath) +} + func SetDefaults() { // CLOUDACCOUNTID DEFAULT Viper.SetDefault(CloudAccountIdKey, Defaults.CloudAccountID) diff --git a/src/core/config/defaults.go b/src/core/config/defaults.go index 4c7adfccb..a4fcfddf5 100644 --- a/src/core/config/defaults.go +++ b/src/core/config/defaults.go @@ -93,6 +93,8 @@ var ( ) const ( + MODULE = "NGINX-AGENT" + DynamicConfigFileName = "agent-dynamic.conf" DynamicConfigFileAbsPath = "/var/lib/nginx-agent/agent-dynamic.conf" DynamicConfigFileAbsFreeBsdPath = "/var/db/nginx-agent/agent-dynamic.conf" diff --git a/src/core/grpc.go b/src/core/grpc.go new file mode 100644 index 000000000..0d22474f7 --- /dev/null +++ b/src/core/grpc.go @@ -0,0 +1,75 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package core + +import ( + "context" + "strings" + + "github.com/google/uuid" + "github.com/nginx/agent/sdk/v2/client" + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/v2/src/core/config" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" +) + +func CreateGrpcClients(ctx context.Context, loadedConfig *config.Config) (client.Controller, client.Commander, client.MetricReporter) { + if !loadedConfig.IsGrpcServerConfigured() { + log.Info("GRPC clients not created due to missing server config") + return nil, nil, nil + } + + grpcDialOptions := setDialOptions(loadedConfig) + secureMetricsDialOpts, err := sdkGRPC.SecureDialOptions( + loadedConfig.TLS.Enable, + loadedConfig.TLS.Cert, + loadedConfig.TLS.Key, + loadedConfig.TLS.Ca, + loadedConfig.Server.Metrics, + loadedConfig.TLS.SkipVerify) + if err != nil { + log.Fatalf("Failed to load secure metric gRPC dial options: %v", err) + } + + secureCmdDialOpts, err := sdkGRPC.SecureDialOptions( + loadedConfig.TLS.Enable, + loadedConfig.TLS.Cert, + loadedConfig.TLS.Key, + loadedConfig.TLS.Ca, + loadedConfig.Server.Command, + loadedConfig.TLS.SkipVerify) + if err != nil { + log.Fatalf("Failed to load secure command gRPC dial options: %v", err) + } + + controller := client.NewClientController() + controller.WithContext(ctx) + commander := client.NewCommanderClient() + commander.WithBackoffSettings(loadedConfig.GetServerBackoffSettings()) + + commander.WithServer(loadedConfig.Server.Target) + commander.WithDialOptions(append(grpcDialOptions, secureCmdDialOpts)...) + + reporter := client.NewMetricReporterClient() + reporter.WithBackoffSettings(loadedConfig.GetServerBackoffSettings()) + reporter.WithServer(loadedConfig.Server.Target) + reporter.WithDialOptions(append(grpcDialOptions, secureMetricsDialOpts)...) + + controller.WithClient(commander) + controller.WithClient(reporter) + + return controller, commander, reporter +} + +func setDialOptions(loadedConfig *config.Config) []grpc.DialOption { + grpcDialOptions := []grpc.DialOption{grpc.WithUserAgent("nginx-agent/" + strings.TrimPrefix(version, "v"))} + grpcDialOptions = append(grpcDialOptions, sdkGRPC.DefaultClientDialOptions...) + grpcDialOptions = append(grpcDialOptions, sdkGRPC.DataplaneConnectionDialOptions(loadedConfig.Server.Token, sdkGRPC.NewMessageMeta(uuid.NewString()))...) + return grpcDialOptions +} diff --git a/src/core/grpc_test.go b/src/core/grpc_test.go new file mode 100644 index 000000000..ea07731f1 --- /dev/null +++ b/src/core/grpc_test.go @@ -0,0 +1,56 @@ +package core + +import ( + "context" + "testing" + + "github.com/nginx/agent/v2/src/core/config" + "github.com/stretchr/testify/assert" +) + +func TestCreateGrpcClients(t *testing.T) { + // Create a mock configuration with proper settings + loadedConfig := &config.Config{ + TLS: config.TLSConfig{ + Enable: true, + Cert: "cert.pem", + Key: "key.pem", + Ca: "ca.pem", + SkipVerify: false, + }, + Server: config.Server{ + Metrics: "metrics-server", + Command: "command-server", + Target: "grpc-server", + }, + } + + ctx := context.Background() + + controller, commander, reporter := CreateGrpcClients(ctx, loadedConfig) + + // Assert that the returned clients are not nil + assert.NotNil(t, controller) + assert.NotNil(t, commander) + assert.NotNil(t, reporter) + + // Additional assertions can be added to test the client configurations + // For example, you can check if the dial options are set correctly. +} + +func TestSetDialOptions(t *testing.T) { + // Create a mock configuration with proper settings + loadedConfig := &config.Config{ + Server: config.Server{ + Token: "your-token", + }, + } + + dialOptions := setDialOptions(loadedConfig) + + // Assert that the dial options are not empty and contain expected options. + assert.NotEmpty(t, dialOptions) + + // You can add more specific assertions based on your expected dial options. + // For example, checking if grpc.WithUserAgent is set, or other options. +} diff --git a/src/core/pipe.go b/src/core/pipe.go index 9b9bbdead..1ded89e02 100644 --- a/src/core/pipe.go +++ b/src/core/pipe.go @@ -54,6 +54,15 @@ func NewMessagePipe(ctx context.Context) *MessagePipe { } } +func InitializePipe(ctx context.Context, corePlugins []Plugin, extensionPlugins []ExtensionPlugin, size int) MessagePipeInterface { + pipe := NewMessagePipe(ctx) + err := pipe.Register(size, corePlugins, extensionPlugins) + if err != nil { + log.Warnf("Failed to start agent successfully, error loading plugins %v", err) + } + return pipe +} + func (p *MessagePipe) Register(size int, plugins []Plugin, extensionPlugins []ExtensionPlugin) error { p.mu.Lock() diff --git a/src/core/signals.go b/src/core/signals.go new file mode 100644 index 000000000..4640a532f --- /dev/null +++ b/src/core/signals.go @@ -0,0 +1,74 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package core + +import ( + "context" + "os" + "os/signal" + "strconv" + "syscall" + "time" + + "github.com/nginx/agent/sdk/v2/agent/events" + "github.com/nginx/agent/sdk/v2/client" + "github.com/nginx/agent/v2/src/core/config" + log "github.com/sirupsen/logrus" +) + +// handleSignals handles signals to attempt graceful shutdown +// for now it also handles sending the agent stopped event because as of today we don't have a mechanism for synchronizing +// tasks between multiple plugins from outside a plugin +func HandleSignals( + ctx context.Context, + cmder client.Commander, + loadedConfig *config.Config, + env Environment, + pipe MessagePipeInterface, + cancel context.CancelFunc, + controller client.Controller, +) { + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + go func() { + select { + case <-sigChan: + event := events.NewAgentEventMeta(config.MODULE, + version, + strconv.Itoa(os.Getpid()), + "Initialize Agent", + env.GetHostname(), + env.GetSystemUUID(), + loadedConfig.InstanceGroup, + loadedConfig.Tags) + + stopCmd := events.GenerateAgentStopEventCommand(event) + log.Debugf("Sending agent stopped event: %v", stopCmd) + + if cmder == nil { + log.Warn("Command channel not configured. Skipping sending AgentStopped event") + } else if err := cmder.Send(ctx, client.MessageFromCommand(stopCmd)); err != nil { + log.Errorf("Error sending AgentStopped event to command channel: %v", err) + } + + if controller != nil { + if err := controller.Close(); err != nil { + log.Warnf("Unable to close controller: %v", err) + } + } + + log.Warn("NGINX Agent exiting") + cancel() + + timeout := time.Second * 5 + time.Sleep(timeout) + log.Fatalf("Failed to gracefully shutdown within timeout of %v. Exiting", timeout) + case <-ctx.Done(): + } + }() +} diff --git a/src/plugins/events.go b/src/plugins/events.go index 2050e5353..cf90d629e 100644 --- a/src/plugins/events.go +++ b/src/plugins/events.go @@ -17,7 +17,7 @@ import ( log "github.com/sirupsen/logrus" agent_config "github.com/nginx/agent/sdk/v2/agent/config" - sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/sdk/v2/agent/events" "github.com/nginx/agent/sdk/v2/proto" commonProto "github.com/nginx/agent/sdk/v2/proto/common" eventsProto "github.com/nginx/agent/sdk/v2/proto/events" @@ -26,8 +26,6 @@ import ( ) const ( - MODULE = "NGINX-AGENT" - AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" NGINX_FOUND_MESSAGE = "nginx-v%s master process was found with a pid %s" @@ -40,22 +38,6 @@ const ( CONFIG_APPLY_FAILURE_MESSAGE = "failed to apply nginx config on %s" CONFIG_ROLLBACK_SUCCESS_MESSAGE = "nginx config was rolled back on %s" CONFIG_ROLLBACK_FAILURE_MESSAGE = "failed to rollback nginx config on %s" - - // Types - NGINX_EVENT_TYPE = "Nginx" - AGENT_EVENT_TYPE = "Agent" - - // Categories - STATUS_CATEGORY = "Status" - CONFIG_CATEGORY = "Config" - APP_PROTECT_CATEGORY = "AppProtect" - - // Event Levels - INFO_EVENT_LEVEL = "INFO" - DEBUG_EVENT_LEVEL = "DEBUG" - WARN_EVENT_LEVEL = "WARN" - ERROR_EVENT_LEVEL = "ERROR" - CRITICAL_EVENT_LEVEL = "CRITICAL" ) type Events struct { @@ -130,7 +112,7 @@ func (a *Events) Subscriptions() []string { } func (a *Events) sendAgentStartedEvent(msg *core.Message) { - agentEventMeta, ok := msg.Data().(*AgentEventMeta) + agentEventMeta, ok := msg.Data().(*events.AgentEventMeta) if !ok { log.Warnf("Invalid message received, %T, for topic, %s", msg.Data(), msg.Topic()) return @@ -138,7 +120,7 @@ func (a *Events) sendAgentStartedEvent(msg *core.Message) { event := a.createAgentEvent( types.TimestampNow(), - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(AGENT_START_MESSAGE, agentEventMeta.version, a.env.GetHostname(), agentEventMeta.pid), uuid.NewString(), ) @@ -162,19 +144,19 @@ func (a *Events) sendNingxFoundEvent(msg *core.Message) { return } - events := []*eventsProto.Event{} + protoEvents := []*eventsProto.Event{} for _, nginxDetail := range nginxDetailsMap { event := a.createNginxEvent( nginxDetail.GetNginxId(), &types.Timestamp{Seconds: nginxDetail.GetStartTime() / 1000, Nanos: int32(nginxDetail.GetStartTime() % 1000)}, - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(NGINX_FOUND_MESSAGE, nginxDetail.GetVersion(), nginxDetail.GetProcessId()), uuid.NewString(), ) log.Debugf("Created event: %v", event) - events = append(events, event) + protoEvents = append(protoEvents, event) } a.pipeline.Process(core.NewMessage(core.Events, &proto.Command{ @@ -182,7 +164,7 @@ func (a *Events) sendNingxFoundEvent(msg *core.Message) { Type: proto.Command_NORMAL, Data: &proto.Command_EventReport{ EventReport: &eventsProto.EventReport{ - Events: events, + Events: protoEvents, }, }, })) @@ -200,7 +182,7 @@ func (a *Events) sendNginxReloadEvent(msg *core.Message) { event = a.createNginxEvent( nginxReload.nginxDetails.GetNginxId(), nginxReload.timestamp, - WARN_EVENT_LEVEL, + events.WARN_EVENT_LEVEL, fmt.Sprintf(NGINX_RELOAD_SUCCESS_MESSAGE, nginxReload.nginxDetails.GetVersion(), nginxReload.nginxDetails.GetProcessId()), nginxReload.correlationId, ) @@ -208,7 +190,7 @@ func (a *Events) sendNginxReloadEvent(msg *core.Message) { event = a.createNginxEvent( nginxReload.nginxDetails.GetNginxId(), nginxReload.timestamp, - ERROR_EVENT_LEVEL, + events.ERROR_EVENT_LEVEL, fmt.Sprintf(NGINX_RELOAD_FAILED_MESSAGE, nginxReload.nginxDetails.GetVersion(), nginxReload.nginxDetails.GetProcessId()), nginxReload.correlationId, ) @@ -249,7 +231,7 @@ func (a *Events) sendConfigApplyEvent(msg *core.Message) { event = a.createConfigApplyEvent( nginxConfigResponse.GetConfigData().GetNginxId(), command.GetMeta().GetTimestamp(), - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(CONFIG_APPLY_SUCCESS_MESSAGE, a.env.GetHostname()), command.Meta.GetMessageId(), ) @@ -257,7 +239,7 @@ func (a *Events) sendConfigApplyEvent(msg *core.Message) { event = a.createConfigApplyEvent( nginxConfigResponse.GetConfigData().GetNginxId(), command.GetMeta().GetTimestamp(), - ERROR_EVENT_LEVEL, + events.ERROR_EVENT_LEVEL, fmt.Sprintf(CONFIG_APPLY_FAILURE_MESSAGE, a.env.GetHostname()), command.Meta.GetMessageId(), ) @@ -291,7 +273,7 @@ func (a *Events) sendConfigRollbackEvent(msg *core.Message) { event = a.createConfigApplyEvent( configRollbackResponse.nginxDetails.GetNginxId(), configRollbackResponse.timestamp, - WARN_EVENT_LEVEL, + events.WARN_EVENT_LEVEL, fmt.Sprintf(CONFIG_ROLLBACK_SUCCESS_MESSAGE, a.env.GetHostname()), configRollbackResponse.correlationId, ) @@ -299,7 +281,7 @@ func (a *Events) sendConfigRollbackEvent(msg *core.Message) { event = a.createConfigApplyEvent( configRollbackResponse.nginxDetails.GetNginxId(), configRollbackResponse.timestamp, - ERROR_EVENT_LEVEL, + events.ERROR_EVENT_LEVEL, fmt.Sprintf(CONFIG_ROLLBACK_FAILURE_MESSAGE, a.env.GetHostname()), configRollbackResponse.correlationId, ) @@ -328,7 +310,7 @@ func (a *Events) sendNginxStartEvent(msg *core.Message) { event := a.createNginxEvent( nginxDetails.GetNginxId(), &types.Timestamp{Seconds: nginxDetails.GetStartTime() / 1000, Nanos: int32(nginxDetails.GetStartTime() % 1000)}, - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(NGINX_FOUND_MESSAGE, nginxDetails.GetVersion(), nginxDetails.GetProcessId()), uuid.NewString(), ) @@ -355,7 +337,7 @@ func (a *Events) sendNginxStopEvent(msg *core.Message) { event := a.createNginxEvent( nginxDetails.GetNginxId(), types.TimestampNow(), - WARN_EVENT_LEVEL, + events.WARN_EVENT_LEVEL, fmt.Sprintf(NGINX_STOP_MESSAGE, nginxDetails.GetVersion(), nginxDetails.GetProcessId()), uuid.NewString(), ) @@ -382,7 +364,7 @@ func (a *Events) sendNginxWorkerStartEvent(msg *core.Message) { event := a.createNginxEvent( nginxDetails.GetNginxId(), &types.Timestamp{Seconds: nginxDetails.GetStartTime() / 1000, Nanos: int32(nginxDetails.GetStartTime() % 1000)}, - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(NGINX_WORKER_START_MESSAGE, nginxDetails.GetProcessId(), nginxDetails.GetVersion(), nginxDetails.GetProcessId()), uuid.NewString(), ) @@ -409,7 +391,7 @@ func (a *Events) sendNginxWorkerStopEvent(msg *core.Message) { event := a.createNginxEvent( nginxDetails.GetNginxId(), types.TimestampNow(), - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(NGINX_WORKER_STOP_MESSAGE, nginxDetails.GetProcessId(), nginxDetails.GetVersion(), nginxDetails.GetProcessId()), uuid.NewString(), ) @@ -433,11 +415,11 @@ func (e *Events) createNginxEvent(nginxId string, timestamp *types.Timestamp, le Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: correlationId, - Module: MODULE, + Module: config.MODULE, Timestamp: timestamp, EventLevel: level, - Type: NGINX_EVENT_TYPE, - Category: STATUS_CATEGORY, + Type: events.NGINX_EVENT_TYPE, + Category: events.STATUS_CATEGORY, }, Data: &eventsProto.Event_ActivityEvent{ ActivityEvent: activityEvent, @@ -452,11 +434,11 @@ func (e *Events) createConfigApplyEvent(nginxId string, timestamp *types.Timesta Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: correlationId, - Module: MODULE, + Module: config.MODULE, Timestamp: timestamp, EventLevel: level, - Type: AGENT_EVENT_TYPE, - Category: CONFIG_CATEGORY, + Type: events.AGENT_EVENT_TYPE, + Category: events.CONFIG_CATEGORY, }, Data: &eventsProto.Event_ActivityEvent{ ActivityEvent: activityEvent, @@ -471,11 +453,11 @@ func (e *Events) createAgentEvent(timestamp *types.Timestamp, level string, mess Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: correlationId, - Module: MODULE, + Module: config.MODULE, Timestamp: timestamp, EventLevel: level, - Type: AGENT_EVENT_TYPE, - Category: STATUS_CATEGORY, + Type: events.AGENT_EVENT_TYPE, + Category: events.STATUS_CATEGORY, }, Data: &eventsProto.Event_ActivityEvent{ ActivityEvent: activityEvent, @@ -513,64 +495,3 @@ func (e *Events) createActivityEvent(message string, nginxId string) *eventsProt return activityEvent } - -type AgentEventMeta struct { - version string - pid string -} - -func NewAgentEventMeta(version string, pid string) *AgentEventMeta { - return &AgentEventMeta{ - version: version, - pid: pid, - } -} - -func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta, conf *config.Config, env core.Environment) *proto.Command { - activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_STOP_MESSAGE, agentEvent.version, agentEvent.pid, env.GetHostname()), - Dimensions: []*commonProto.Dimension{ - { - Name: "system_id", - Value: env.GetSystemUUID(), - }, - { - Name: "hostname", - Value: env.GetHostname(), - }, - { - Name: "instance_group", - Value: conf.InstanceGroup, - }, - { - Name: "system.tags", - Value: strings.Join(conf.Tags, ","), - }, - }, - } - - event := &eventsProto.Event{ - Metadata: &eventsProto.Metadata{ - UUID: uuid.NewString(), - CorrelationID: uuid.NewString(), - Module: MODULE, - Timestamp: types.TimestampNow(), - EventLevel: WARN_EVENT_LEVEL, - Type: AGENT_EVENT_TYPE, - Category: STATUS_CATEGORY, - }, - Data: &eventsProto.Event_ActivityEvent{ - ActivityEvent: activityEvent, - }, - } - - return &proto.Command{ - Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), - Type: proto.Command_NORMAL, - Data: &proto.Command_EventReport{ - EventReport: &eventsProto.EventReport{ - Events: []*eventsProto.Event{event}, - }, - }, - } -} diff --git a/src/plugins/events_test.go b/src/plugins/events_test.go index 3ee4a1305..cbbfd7164 100644 --- a/src/plugins/events_test.go +++ b/src/plugins/events_test.go @@ -14,6 +14,7 @@ import ( "github.com/gogo/protobuf/types" "github.com/google/uuid" + "github.com/nginx/agent/sdk/v2/agent/events" "github.com/nginx/agent/sdk/v2/grpc" "github.com/nginx/agent/sdk/v2/proto" commonProto "github.com/nginx/agent/sdk/v2/proto/common" @@ -335,7 +336,7 @@ func TestActivityEvents_Process(t *testing.T) { }, { name: "test AgentStart message", - message: core.NewMessage(core.AgentStarted, &AgentEventMeta{version: "v0.0.1", pid: "75231"}), + message: core.NewMessage(core.AgentStarted, &events.AgentEventMeta{version: "v0.0.1", pid: "75231"}), msgTopics: []string{ core.AgentStarted, core.Events, @@ -597,8 +598,19 @@ func TestGenerateAgentStopEvent(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { env := tutils.NewMockEnvironment() - - agentStopCmd := GenerateAgentStopEventCommand(&AgentEventMeta{version: tt.agentVersion, pid: tt.pid}, tt.conf, env) + // agentEventMeta := tt.expectedEvent.GetData().(*events.AgentEventMeta) + // message := tt.expectedEvent.GetData() + meta := events.NewAgentEventMeta( + config.MODULE, + tt.agentVersion, + tt.pid, + "", + env.GetHostname(), + env.GetSystemUUID(), + tt.conf.InstanceGroup, + tt.conf.Tags, + ) + agentStopCmd := events.GenerateAgentStopEventCommand(meta) actualEvent := agentStopCmd.GetEventReport().Events[0] // assert metadata diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go new file mode 100644 index 000000000..ca2885dff --- /dev/null +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -0,0 +1,96 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package events + +import ( + "fmt" + "strings" + + "github.com/gogo/protobuf/types" + "github.com/google/uuid" + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/sdk/v2/proto" + commonProto "github.com/nginx/agent/sdk/v2/proto/common" + eventsProto "github.com/nginx/agent/sdk/v2/proto/events" +) + +type AgentEventMeta struct { + module string + version string + pid string + message string + hostname string + systemUuid string + instanceGroup string + tags []string +} + +func NewAgentEventMeta( + module, version, pid, message, hostname, systemUuid, instanceGroup string, + tags []string, +) *AgentEventMeta { + return &AgentEventMeta{ + module: module, + version: version, + pid: pid, + message: message, + hostname: hostname, + systemUuid: systemUuid, + instanceGroup: instanceGroup, + tags: tags, + } +} + +func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { + activityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf(agentEvent.message, agentEvent.version, agentEvent.pid, agentEvent.hostname), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: agentEvent.systemUuid, + }, + { + Name: "hostname", + Value: agentEvent.hostname, + }, + { + Name: "instance_group", + Value: agentEvent.instanceGroup, + }, + { + Name: "system.tags", + Value: strings.Join(agentEvent.tags, ","), + }, + }, + } + + event := &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: uuid.NewString(), + Module: agentEvent.module, + Timestamp: types.TimestampNow(), + EventLevel: WARN_EVENT_LEVEL, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } + + return &proto.Command{ + Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), + Type: proto.Command_NORMAL, + Data: &proto.Command_EventReport{ + EventReport: &eventsProto.EventReport{ + Events: []*eventsProto.Event{event}, + }, + }, + } +} diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go new file mode 100644 index 000000000..0340d130d --- /dev/null +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -0,0 +1,19 @@ +package events + +const ( + // Types + NGINX_EVENT_TYPE = "Nginx" + AGENT_EVENT_TYPE = "Agent" + + // Categories + STATUS_CATEGORY = "Status" + CONFIG_CATEGORY = "Config" + APP_PROTECT_CATEGORY = "AppProtect" + + // Event Levels + INFO_EVENT_LEVEL = "INFO" + DEBUG_EVENT_LEVEL = "DEBUG" + WARN_EVENT_LEVEL = "WARN" + ERROR_EVENT_LEVEL = "ERROR" + CRITICAL_EVENT_LEVEL = "CRITICAL" +) diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/config.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/config.go index 638ebff64..4f6983717 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/config.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/config.go @@ -62,6 +62,22 @@ func Execute() error { return ROOT_COMMAND.Execute() } +func InitConfiguration(version, commit string) { + SetVersion(version, commit) + SetDefaults() + RegisterFlags() + dynamicConfigPath := DynamicConfigFileAbsPath + if runtime.GOOS == "freebsd" { + dynamicConfigPath = DynamicConfigFileAbsFreeBsdPath + } + configPath, err := RegisterConfigFile(dynamicConfigPath, ConfigFileName, ConfigFilePaths()...) + if err != nil { + log.Fatalf("Failed to load configuration file: %v", err) + } + log.Debugf("Configuration file loaded %v", configPath) + Viper.Set(ConfigPathKey, configPath) +} + func SetDefaults() { // CLOUDACCOUNTID DEFAULT Viper.SetDefault(CloudAccountIdKey, Defaults.CloudAccountID) diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go index 4c7adfccb..a4fcfddf5 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go @@ -93,6 +93,8 @@ var ( ) const ( + MODULE = "NGINX-AGENT" + DynamicConfigFileName = "agent-dynamic.conf" DynamicConfigFileAbsPath = "/var/lib/nginx-agent/agent-dynamic.conf" DynamicConfigFileAbsFreeBsdPath = "/var/db/nginx-agent/agent-dynamic.conf" diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/grpc.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/grpc.go new file mode 100644 index 000000000..0d22474f7 --- /dev/null +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/grpc.go @@ -0,0 +1,75 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package core + +import ( + "context" + "strings" + + "github.com/google/uuid" + "github.com/nginx/agent/sdk/v2/client" + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/v2/src/core/config" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" +) + +func CreateGrpcClients(ctx context.Context, loadedConfig *config.Config) (client.Controller, client.Commander, client.MetricReporter) { + if !loadedConfig.IsGrpcServerConfigured() { + log.Info("GRPC clients not created due to missing server config") + return nil, nil, nil + } + + grpcDialOptions := setDialOptions(loadedConfig) + secureMetricsDialOpts, err := sdkGRPC.SecureDialOptions( + loadedConfig.TLS.Enable, + loadedConfig.TLS.Cert, + loadedConfig.TLS.Key, + loadedConfig.TLS.Ca, + loadedConfig.Server.Metrics, + loadedConfig.TLS.SkipVerify) + if err != nil { + log.Fatalf("Failed to load secure metric gRPC dial options: %v", err) + } + + secureCmdDialOpts, err := sdkGRPC.SecureDialOptions( + loadedConfig.TLS.Enable, + loadedConfig.TLS.Cert, + loadedConfig.TLS.Key, + loadedConfig.TLS.Ca, + loadedConfig.Server.Command, + loadedConfig.TLS.SkipVerify) + if err != nil { + log.Fatalf("Failed to load secure command gRPC dial options: %v", err) + } + + controller := client.NewClientController() + controller.WithContext(ctx) + commander := client.NewCommanderClient() + commander.WithBackoffSettings(loadedConfig.GetServerBackoffSettings()) + + commander.WithServer(loadedConfig.Server.Target) + commander.WithDialOptions(append(grpcDialOptions, secureCmdDialOpts)...) + + reporter := client.NewMetricReporterClient() + reporter.WithBackoffSettings(loadedConfig.GetServerBackoffSettings()) + reporter.WithServer(loadedConfig.Server.Target) + reporter.WithDialOptions(append(grpcDialOptions, secureMetricsDialOpts)...) + + controller.WithClient(commander) + controller.WithClient(reporter) + + return controller, commander, reporter +} + +func setDialOptions(loadedConfig *config.Config) []grpc.DialOption { + grpcDialOptions := []grpc.DialOption{grpc.WithUserAgent("nginx-agent/" + strings.TrimPrefix(version, "v"))} + grpcDialOptions = append(grpcDialOptions, sdkGRPC.DefaultClientDialOptions...) + grpcDialOptions = append(grpcDialOptions, sdkGRPC.DataplaneConnectionDialOptions(loadedConfig.Server.Token, sdkGRPC.NewMessageMeta(uuid.NewString()))...) + return grpcDialOptions +} diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/pipe.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/pipe.go index 9b9bbdead..1ded89e02 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/src/core/pipe.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/pipe.go @@ -54,6 +54,15 @@ func NewMessagePipe(ctx context.Context) *MessagePipe { } } +func InitializePipe(ctx context.Context, corePlugins []Plugin, extensionPlugins []ExtensionPlugin, size int) MessagePipeInterface { + pipe := NewMessagePipe(ctx) + err := pipe.Register(size, corePlugins, extensionPlugins) + if err != nil { + log.Warnf("Failed to start agent successfully, error loading plugins %v", err) + } + return pipe +} + func (p *MessagePipe) Register(size int, plugins []Plugin, extensionPlugins []ExtensionPlugin) error { p.mu.Lock() diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go new file mode 100644 index 000000000..4640a532f --- /dev/null +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go @@ -0,0 +1,74 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package core + +import ( + "context" + "os" + "os/signal" + "strconv" + "syscall" + "time" + + "github.com/nginx/agent/sdk/v2/agent/events" + "github.com/nginx/agent/sdk/v2/client" + "github.com/nginx/agent/v2/src/core/config" + log "github.com/sirupsen/logrus" +) + +// handleSignals handles signals to attempt graceful shutdown +// for now it also handles sending the agent stopped event because as of today we don't have a mechanism for synchronizing +// tasks between multiple plugins from outside a plugin +func HandleSignals( + ctx context.Context, + cmder client.Commander, + loadedConfig *config.Config, + env Environment, + pipe MessagePipeInterface, + cancel context.CancelFunc, + controller client.Controller, +) { + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + go func() { + select { + case <-sigChan: + event := events.NewAgentEventMeta(config.MODULE, + version, + strconv.Itoa(os.Getpid()), + "Initialize Agent", + env.GetHostname(), + env.GetSystemUUID(), + loadedConfig.InstanceGroup, + loadedConfig.Tags) + + stopCmd := events.GenerateAgentStopEventCommand(event) + log.Debugf("Sending agent stopped event: %v", stopCmd) + + if cmder == nil { + log.Warn("Command channel not configured. Skipping sending AgentStopped event") + } else if err := cmder.Send(ctx, client.MessageFromCommand(stopCmd)); err != nil { + log.Errorf("Error sending AgentStopped event to command channel: %v", err) + } + + if controller != nil { + if err := controller.Close(); err != nil { + log.Warnf("Unable to close controller: %v", err) + } + } + + log.Warn("NGINX Agent exiting") + cancel() + + timeout := time.Second * 5 + time.Sleep(timeout) + log.Fatalf("Failed to gracefully shutdown within timeout of %v. Exiting", timeout) + case <-ctx.Done(): + } + }() +} diff --git a/test/integration/vendor/modules.txt b/test/integration/vendor/modules.txt index d8d3101fc..fde2702a6 100644 --- a/test/integration/vendor/modules.txt +++ b/test/integration/vendor/modules.txt @@ -649,6 +649,7 @@ github.com/munnerz/goautoneg ## explicit; go 1.21 github.com/nginx/agent/sdk/v2 github.com/nginx/agent/sdk/v2/agent/config +github.com/nginx/agent/sdk/v2/agent/events github.com/nginx/agent/sdk/v2/backoff github.com/nginx/agent/sdk/v2/checksum github.com/nginx/agent/sdk/v2/client diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index 408c43ab0..78e36b6d4 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -125,3 +125,61 @@ func BenchmarkPluginOneTimeRegistration(b *testing.B) { cancel() <-pipelineDone } + +func BenchmarkPluginOneTimeRegistration(b *testing.B) { + var pluginsUnderTest []core.Plugin + + ctx, cancel := context.WithCancel(context.Background()) + pipelineDone := make(chan bool) + + config := config.Config{Nginx: config.Nginx{Debug: true}} + + processID := "12345" + detailsMap := map[string]*proto.NginxDetails{ + processID: { + ProcessPath: "/path/to/nginx", + NginxId: processID, + }, + } + + binary := utils.NewMockNginxBinary() + binary.On("GetNginxDetailsMapFromProcesses", mock.Anything).Return(detailsMap) + binary.On("GetNginxIDForProcess", mock.Anything).Return(processID) + binary.On("GetNginxDetailsFromProcess", mock.Anything).Return(detailsMap[processID]) + binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) + + env := utils.NewMockEnvironment() + env.Mock.On("NewHostInfo", mock.Anything, mock.Anything, mock.Anything).Return(&proto.HostInfo{ + Hostname: "test-host", + }) + env.Mock.On("Processes", mock.Anything).Return([]*core.Process{ + { + Name: processID, + IsMaster: true, + }, + }) + + meta := proto.Metadata{} + version := "1234" + + messagePipe := core.NewMessagePipe(ctx) + for n := 0; n < b.N; n++ { + pluginsUnderTest = append(pluginsUnderTest, plugins.NewOneTimeRegistration(&config, binary, env, &meta, version)) + } + + err := messagePipe.Register(b.N, pluginsUnderTest, []core.ExtensionPlugin{}) + assert.NoError(b, err) + + go func() { + messagePipe.Run() + pipelineDone <- true + }() + + for n := 0; n < b.N; n++ { + messagePipe.Process(core.NewMessage(core.UNKNOWN, n)) + time.Sleep(200 * time.Millisecond) // for the above call being asynchronous + } + + cancel() + <-pipelineDone +} diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go new file mode 100644 index 000000000..ca2885dff --- /dev/null +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -0,0 +1,96 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package events + +import ( + "fmt" + "strings" + + "github.com/gogo/protobuf/types" + "github.com/google/uuid" + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/sdk/v2/proto" + commonProto "github.com/nginx/agent/sdk/v2/proto/common" + eventsProto "github.com/nginx/agent/sdk/v2/proto/events" +) + +type AgentEventMeta struct { + module string + version string + pid string + message string + hostname string + systemUuid string + instanceGroup string + tags []string +} + +func NewAgentEventMeta( + module, version, pid, message, hostname, systemUuid, instanceGroup string, + tags []string, +) *AgentEventMeta { + return &AgentEventMeta{ + module: module, + version: version, + pid: pid, + message: message, + hostname: hostname, + systemUuid: systemUuid, + instanceGroup: instanceGroup, + tags: tags, + } +} + +func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { + activityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf(agentEvent.message, agentEvent.version, agentEvent.pid, agentEvent.hostname), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: agentEvent.systemUuid, + }, + { + Name: "hostname", + Value: agentEvent.hostname, + }, + { + Name: "instance_group", + Value: agentEvent.instanceGroup, + }, + { + Name: "system.tags", + Value: strings.Join(agentEvent.tags, ","), + }, + }, + } + + event := &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: uuid.NewString(), + Module: agentEvent.module, + Timestamp: types.TimestampNow(), + EventLevel: WARN_EVENT_LEVEL, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } + + return &proto.Command{ + Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), + Type: proto.Command_NORMAL, + Data: &proto.Command_EventReport{ + EventReport: &eventsProto.EventReport{ + Events: []*eventsProto.Event{event}, + }, + }, + } +} diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go new file mode 100644 index 000000000..0340d130d --- /dev/null +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -0,0 +1,19 @@ +package events + +const ( + // Types + NGINX_EVENT_TYPE = "Nginx" + AGENT_EVENT_TYPE = "Agent" + + // Categories + STATUS_CATEGORY = "Status" + CONFIG_CATEGORY = "Config" + APP_PROTECT_CATEGORY = "AppProtect" + + // Event Levels + INFO_EVENT_LEVEL = "INFO" + DEBUG_EVENT_LEVEL = "DEBUG" + WARN_EVENT_LEVEL = "WARN" + ERROR_EVENT_LEVEL = "ERROR" + CRITICAL_EVENT_LEVEL = "CRITICAL" +) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go index 638ebff64..4f6983717 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go @@ -62,6 +62,22 @@ func Execute() error { return ROOT_COMMAND.Execute() } +func InitConfiguration(version, commit string) { + SetVersion(version, commit) + SetDefaults() + RegisterFlags() + dynamicConfigPath := DynamicConfigFileAbsPath + if runtime.GOOS == "freebsd" { + dynamicConfigPath = DynamicConfigFileAbsFreeBsdPath + } + configPath, err := RegisterConfigFile(dynamicConfigPath, ConfigFileName, ConfigFilePaths()...) + if err != nil { + log.Fatalf("Failed to load configuration file: %v", err) + } + log.Debugf("Configuration file loaded %v", configPath) + Viper.Set(ConfigPathKey, configPath) +} + func SetDefaults() { // CLOUDACCOUNTID DEFAULT Viper.SetDefault(CloudAccountIdKey, Defaults.CloudAccountID) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go index 4c7adfccb..a4fcfddf5 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go @@ -93,6 +93,8 @@ var ( ) const ( + MODULE = "NGINX-AGENT" + DynamicConfigFileName = "agent-dynamic.conf" DynamicConfigFileAbsPath = "/var/lib/nginx-agent/agent-dynamic.conf" DynamicConfigFileAbsFreeBsdPath = "/var/db/nginx-agent/agent-dynamic.conf" diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/grpc.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/grpc.go new file mode 100644 index 000000000..0d22474f7 --- /dev/null +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/grpc.go @@ -0,0 +1,75 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package core + +import ( + "context" + "strings" + + "github.com/google/uuid" + "github.com/nginx/agent/sdk/v2/client" + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/v2/src/core/config" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc" +) + +func CreateGrpcClients(ctx context.Context, loadedConfig *config.Config) (client.Controller, client.Commander, client.MetricReporter) { + if !loadedConfig.IsGrpcServerConfigured() { + log.Info("GRPC clients not created due to missing server config") + return nil, nil, nil + } + + grpcDialOptions := setDialOptions(loadedConfig) + secureMetricsDialOpts, err := sdkGRPC.SecureDialOptions( + loadedConfig.TLS.Enable, + loadedConfig.TLS.Cert, + loadedConfig.TLS.Key, + loadedConfig.TLS.Ca, + loadedConfig.Server.Metrics, + loadedConfig.TLS.SkipVerify) + if err != nil { + log.Fatalf("Failed to load secure metric gRPC dial options: %v", err) + } + + secureCmdDialOpts, err := sdkGRPC.SecureDialOptions( + loadedConfig.TLS.Enable, + loadedConfig.TLS.Cert, + loadedConfig.TLS.Key, + loadedConfig.TLS.Ca, + loadedConfig.Server.Command, + loadedConfig.TLS.SkipVerify) + if err != nil { + log.Fatalf("Failed to load secure command gRPC dial options: %v", err) + } + + controller := client.NewClientController() + controller.WithContext(ctx) + commander := client.NewCommanderClient() + commander.WithBackoffSettings(loadedConfig.GetServerBackoffSettings()) + + commander.WithServer(loadedConfig.Server.Target) + commander.WithDialOptions(append(grpcDialOptions, secureCmdDialOpts)...) + + reporter := client.NewMetricReporterClient() + reporter.WithBackoffSettings(loadedConfig.GetServerBackoffSettings()) + reporter.WithServer(loadedConfig.Server.Target) + reporter.WithDialOptions(append(grpcDialOptions, secureMetricsDialOpts)...) + + controller.WithClient(commander) + controller.WithClient(reporter) + + return controller, commander, reporter +} + +func setDialOptions(loadedConfig *config.Config) []grpc.DialOption { + grpcDialOptions := []grpc.DialOption{grpc.WithUserAgent("nginx-agent/" + strings.TrimPrefix(version, "v"))} + grpcDialOptions = append(grpcDialOptions, sdkGRPC.DefaultClientDialOptions...) + grpcDialOptions = append(grpcDialOptions, sdkGRPC.DataplaneConnectionDialOptions(loadedConfig.Server.Token, sdkGRPC.NewMessageMeta(uuid.NewString()))...) + return grpcDialOptions +} diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/pipe.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/pipe.go index 9b9bbdead..1ded89e02 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/pipe.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/pipe.go @@ -54,6 +54,15 @@ func NewMessagePipe(ctx context.Context) *MessagePipe { } } +func InitializePipe(ctx context.Context, corePlugins []Plugin, extensionPlugins []ExtensionPlugin, size int) MessagePipeInterface { + pipe := NewMessagePipe(ctx) + err := pipe.Register(size, corePlugins, extensionPlugins) + if err != nil { + log.Warnf("Failed to start agent successfully, error loading plugins %v", err) + } + return pipe +} + func (p *MessagePipe) Register(size int, plugins []Plugin, extensionPlugins []ExtensionPlugin) error { p.mu.Lock() diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go new file mode 100644 index 000000000..4640a532f --- /dev/null +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go @@ -0,0 +1,74 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package core + +import ( + "context" + "os" + "os/signal" + "strconv" + "syscall" + "time" + + "github.com/nginx/agent/sdk/v2/agent/events" + "github.com/nginx/agent/sdk/v2/client" + "github.com/nginx/agent/v2/src/core/config" + log "github.com/sirupsen/logrus" +) + +// handleSignals handles signals to attempt graceful shutdown +// for now it also handles sending the agent stopped event because as of today we don't have a mechanism for synchronizing +// tasks between multiple plugins from outside a plugin +func HandleSignals( + ctx context.Context, + cmder client.Commander, + loadedConfig *config.Config, + env Environment, + pipe MessagePipeInterface, + cancel context.CancelFunc, + controller client.Controller, +) { + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + go func() { + select { + case <-sigChan: + event := events.NewAgentEventMeta(config.MODULE, + version, + strconv.Itoa(os.Getpid()), + "Initialize Agent", + env.GetHostname(), + env.GetSystemUUID(), + loadedConfig.InstanceGroup, + loadedConfig.Tags) + + stopCmd := events.GenerateAgentStopEventCommand(event) + log.Debugf("Sending agent stopped event: %v", stopCmd) + + if cmder == nil { + log.Warn("Command channel not configured. Skipping sending AgentStopped event") + } else if err := cmder.Send(ctx, client.MessageFromCommand(stopCmd)); err != nil { + log.Errorf("Error sending AgentStopped event to command channel: %v", err) + } + + if controller != nil { + if err := controller.Close(); err != nil { + log.Warnf("Unable to close controller: %v", err) + } + } + + log.Warn("NGINX Agent exiting") + cancel() + + timeout := time.Second * 5 + time.Sleep(timeout) + log.Fatalf("Failed to gracefully shutdown within timeout of %v. Exiting", timeout) + case <-ctx.Done(): + } + }() +} diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go index 2050e5353..cf90d629e 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go @@ -17,7 +17,7 @@ import ( log "github.com/sirupsen/logrus" agent_config "github.com/nginx/agent/sdk/v2/agent/config" - sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/sdk/v2/agent/events" "github.com/nginx/agent/sdk/v2/proto" commonProto "github.com/nginx/agent/sdk/v2/proto/common" eventsProto "github.com/nginx/agent/sdk/v2/proto/events" @@ -26,8 +26,6 @@ import ( ) const ( - MODULE = "NGINX-AGENT" - AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" NGINX_FOUND_MESSAGE = "nginx-v%s master process was found with a pid %s" @@ -40,22 +38,6 @@ const ( CONFIG_APPLY_FAILURE_MESSAGE = "failed to apply nginx config on %s" CONFIG_ROLLBACK_SUCCESS_MESSAGE = "nginx config was rolled back on %s" CONFIG_ROLLBACK_FAILURE_MESSAGE = "failed to rollback nginx config on %s" - - // Types - NGINX_EVENT_TYPE = "Nginx" - AGENT_EVENT_TYPE = "Agent" - - // Categories - STATUS_CATEGORY = "Status" - CONFIG_CATEGORY = "Config" - APP_PROTECT_CATEGORY = "AppProtect" - - // Event Levels - INFO_EVENT_LEVEL = "INFO" - DEBUG_EVENT_LEVEL = "DEBUG" - WARN_EVENT_LEVEL = "WARN" - ERROR_EVENT_LEVEL = "ERROR" - CRITICAL_EVENT_LEVEL = "CRITICAL" ) type Events struct { @@ -130,7 +112,7 @@ func (a *Events) Subscriptions() []string { } func (a *Events) sendAgentStartedEvent(msg *core.Message) { - agentEventMeta, ok := msg.Data().(*AgentEventMeta) + agentEventMeta, ok := msg.Data().(*events.AgentEventMeta) if !ok { log.Warnf("Invalid message received, %T, for topic, %s", msg.Data(), msg.Topic()) return @@ -138,7 +120,7 @@ func (a *Events) sendAgentStartedEvent(msg *core.Message) { event := a.createAgentEvent( types.TimestampNow(), - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(AGENT_START_MESSAGE, agentEventMeta.version, a.env.GetHostname(), agentEventMeta.pid), uuid.NewString(), ) @@ -162,19 +144,19 @@ func (a *Events) sendNingxFoundEvent(msg *core.Message) { return } - events := []*eventsProto.Event{} + protoEvents := []*eventsProto.Event{} for _, nginxDetail := range nginxDetailsMap { event := a.createNginxEvent( nginxDetail.GetNginxId(), &types.Timestamp{Seconds: nginxDetail.GetStartTime() / 1000, Nanos: int32(nginxDetail.GetStartTime() % 1000)}, - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(NGINX_FOUND_MESSAGE, nginxDetail.GetVersion(), nginxDetail.GetProcessId()), uuid.NewString(), ) log.Debugf("Created event: %v", event) - events = append(events, event) + protoEvents = append(protoEvents, event) } a.pipeline.Process(core.NewMessage(core.Events, &proto.Command{ @@ -182,7 +164,7 @@ func (a *Events) sendNingxFoundEvent(msg *core.Message) { Type: proto.Command_NORMAL, Data: &proto.Command_EventReport{ EventReport: &eventsProto.EventReport{ - Events: events, + Events: protoEvents, }, }, })) @@ -200,7 +182,7 @@ func (a *Events) sendNginxReloadEvent(msg *core.Message) { event = a.createNginxEvent( nginxReload.nginxDetails.GetNginxId(), nginxReload.timestamp, - WARN_EVENT_LEVEL, + events.WARN_EVENT_LEVEL, fmt.Sprintf(NGINX_RELOAD_SUCCESS_MESSAGE, nginxReload.nginxDetails.GetVersion(), nginxReload.nginxDetails.GetProcessId()), nginxReload.correlationId, ) @@ -208,7 +190,7 @@ func (a *Events) sendNginxReloadEvent(msg *core.Message) { event = a.createNginxEvent( nginxReload.nginxDetails.GetNginxId(), nginxReload.timestamp, - ERROR_EVENT_LEVEL, + events.ERROR_EVENT_LEVEL, fmt.Sprintf(NGINX_RELOAD_FAILED_MESSAGE, nginxReload.nginxDetails.GetVersion(), nginxReload.nginxDetails.GetProcessId()), nginxReload.correlationId, ) @@ -249,7 +231,7 @@ func (a *Events) sendConfigApplyEvent(msg *core.Message) { event = a.createConfigApplyEvent( nginxConfigResponse.GetConfigData().GetNginxId(), command.GetMeta().GetTimestamp(), - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(CONFIG_APPLY_SUCCESS_MESSAGE, a.env.GetHostname()), command.Meta.GetMessageId(), ) @@ -257,7 +239,7 @@ func (a *Events) sendConfigApplyEvent(msg *core.Message) { event = a.createConfigApplyEvent( nginxConfigResponse.GetConfigData().GetNginxId(), command.GetMeta().GetTimestamp(), - ERROR_EVENT_LEVEL, + events.ERROR_EVENT_LEVEL, fmt.Sprintf(CONFIG_APPLY_FAILURE_MESSAGE, a.env.GetHostname()), command.Meta.GetMessageId(), ) @@ -291,7 +273,7 @@ func (a *Events) sendConfigRollbackEvent(msg *core.Message) { event = a.createConfigApplyEvent( configRollbackResponse.nginxDetails.GetNginxId(), configRollbackResponse.timestamp, - WARN_EVENT_LEVEL, + events.WARN_EVENT_LEVEL, fmt.Sprintf(CONFIG_ROLLBACK_SUCCESS_MESSAGE, a.env.GetHostname()), configRollbackResponse.correlationId, ) @@ -299,7 +281,7 @@ func (a *Events) sendConfigRollbackEvent(msg *core.Message) { event = a.createConfigApplyEvent( configRollbackResponse.nginxDetails.GetNginxId(), configRollbackResponse.timestamp, - ERROR_EVENT_LEVEL, + events.ERROR_EVENT_LEVEL, fmt.Sprintf(CONFIG_ROLLBACK_FAILURE_MESSAGE, a.env.GetHostname()), configRollbackResponse.correlationId, ) @@ -328,7 +310,7 @@ func (a *Events) sendNginxStartEvent(msg *core.Message) { event := a.createNginxEvent( nginxDetails.GetNginxId(), &types.Timestamp{Seconds: nginxDetails.GetStartTime() / 1000, Nanos: int32(nginxDetails.GetStartTime() % 1000)}, - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(NGINX_FOUND_MESSAGE, nginxDetails.GetVersion(), nginxDetails.GetProcessId()), uuid.NewString(), ) @@ -355,7 +337,7 @@ func (a *Events) sendNginxStopEvent(msg *core.Message) { event := a.createNginxEvent( nginxDetails.GetNginxId(), types.TimestampNow(), - WARN_EVENT_LEVEL, + events.WARN_EVENT_LEVEL, fmt.Sprintf(NGINX_STOP_MESSAGE, nginxDetails.GetVersion(), nginxDetails.GetProcessId()), uuid.NewString(), ) @@ -382,7 +364,7 @@ func (a *Events) sendNginxWorkerStartEvent(msg *core.Message) { event := a.createNginxEvent( nginxDetails.GetNginxId(), &types.Timestamp{Seconds: nginxDetails.GetStartTime() / 1000, Nanos: int32(nginxDetails.GetStartTime() % 1000)}, - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(NGINX_WORKER_START_MESSAGE, nginxDetails.GetProcessId(), nginxDetails.GetVersion(), nginxDetails.GetProcessId()), uuid.NewString(), ) @@ -409,7 +391,7 @@ func (a *Events) sendNginxWorkerStopEvent(msg *core.Message) { event := a.createNginxEvent( nginxDetails.GetNginxId(), types.TimestampNow(), - INFO_EVENT_LEVEL, + events.INFO_EVENT_LEVEL, fmt.Sprintf(NGINX_WORKER_STOP_MESSAGE, nginxDetails.GetProcessId(), nginxDetails.GetVersion(), nginxDetails.GetProcessId()), uuid.NewString(), ) @@ -433,11 +415,11 @@ func (e *Events) createNginxEvent(nginxId string, timestamp *types.Timestamp, le Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: correlationId, - Module: MODULE, + Module: config.MODULE, Timestamp: timestamp, EventLevel: level, - Type: NGINX_EVENT_TYPE, - Category: STATUS_CATEGORY, + Type: events.NGINX_EVENT_TYPE, + Category: events.STATUS_CATEGORY, }, Data: &eventsProto.Event_ActivityEvent{ ActivityEvent: activityEvent, @@ -452,11 +434,11 @@ func (e *Events) createConfigApplyEvent(nginxId string, timestamp *types.Timesta Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: correlationId, - Module: MODULE, + Module: config.MODULE, Timestamp: timestamp, EventLevel: level, - Type: AGENT_EVENT_TYPE, - Category: CONFIG_CATEGORY, + Type: events.AGENT_EVENT_TYPE, + Category: events.CONFIG_CATEGORY, }, Data: &eventsProto.Event_ActivityEvent{ ActivityEvent: activityEvent, @@ -471,11 +453,11 @@ func (e *Events) createAgentEvent(timestamp *types.Timestamp, level string, mess Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: correlationId, - Module: MODULE, + Module: config.MODULE, Timestamp: timestamp, EventLevel: level, - Type: AGENT_EVENT_TYPE, - Category: STATUS_CATEGORY, + Type: events.AGENT_EVENT_TYPE, + Category: events.STATUS_CATEGORY, }, Data: &eventsProto.Event_ActivityEvent{ ActivityEvent: activityEvent, @@ -513,64 +495,3 @@ func (e *Events) createActivityEvent(message string, nginxId string) *eventsProt return activityEvent } - -type AgentEventMeta struct { - version string - pid string -} - -func NewAgentEventMeta(version string, pid string) *AgentEventMeta { - return &AgentEventMeta{ - version: version, - pid: pid, - } -} - -func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta, conf *config.Config, env core.Environment) *proto.Command { - activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_STOP_MESSAGE, agentEvent.version, agentEvent.pid, env.GetHostname()), - Dimensions: []*commonProto.Dimension{ - { - Name: "system_id", - Value: env.GetSystemUUID(), - }, - { - Name: "hostname", - Value: env.GetHostname(), - }, - { - Name: "instance_group", - Value: conf.InstanceGroup, - }, - { - Name: "system.tags", - Value: strings.Join(conf.Tags, ","), - }, - }, - } - - event := &eventsProto.Event{ - Metadata: &eventsProto.Metadata{ - UUID: uuid.NewString(), - CorrelationID: uuid.NewString(), - Module: MODULE, - Timestamp: types.TimestampNow(), - EventLevel: WARN_EVENT_LEVEL, - Type: AGENT_EVENT_TYPE, - Category: STATUS_CATEGORY, - }, - Data: &eventsProto.Event_ActivityEvent{ - ActivityEvent: activityEvent, - }, - } - - return &proto.Command{ - Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), - Type: proto.Command_NORMAL, - Data: &proto.Command_EventReport{ - EventReport: &eventsProto.EventReport{ - Events: []*eventsProto.Event{event}, - }, - }, - } -} diff --git a/test/performance/vendor/modules.txt b/test/performance/vendor/modules.txt index a97ea9fa2..0948ac12c 100644 --- a/test/performance/vendor/modules.txt +++ b/test/performance/vendor/modules.txt @@ -128,6 +128,7 @@ github.com/nats-io/nuid ## explicit; go 1.21 github.com/nginx/agent/sdk/v2 github.com/nginx/agent/sdk/v2/agent/config +github.com/nginx/agent/sdk/v2/agent/events github.com/nginx/agent/sdk/v2/backoff github.com/nginx/agent/sdk/v2/checksum github.com/nginx/agent/sdk/v2/client diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go new file mode 100644 index 000000000..ca2885dff --- /dev/null +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -0,0 +1,96 @@ +/** + * Copyright (c) F5, Inc. + * + * This source code is licensed under the Apache License, Version 2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +package events + +import ( + "fmt" + "strings" + + "github.com/gogo/protobuf/types" + "github.com/google/uuid" + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + "github.com/nginx/agent/sdk/v2/proto" + commonProto "github.com/nginx/agent/sdk/v2/proto/common" + eventsProto "github.com/nginx/agent/sdk/v2/proto/events" +) + +type AgentEventMeta struct { + module string + version string + pid string + message string + hostname string + systemUuid string + instanceGroup string + tags []string +} + +func NewAgentEventMeta( + module, version, pid, message, hostname, systemUuid, instanceGroup string, + tags []string, +) *AgentEventMeta { + return &AgentEventMeta{ + module: module, + version: version, + pid: pid, + message: message, + hostname: hostname, + systemUuid: systemUuid, + instanceGroup: instanceGroup, + tags: tags, + } +} + +func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { + activityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf(agentEvent.message, agentEvent.version, agentEvent.pid, agentEvent.hostname), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: agentEvent.systemUuid, + }, + { + Name: "hostname", + Value: agentEvent.hostname, + }, + { + Name: "instance_group", + Value: agentEvent.instanceGroup, + }, + { + Name: "system.tags", + Value: strings.Join(agentEvent.tags, ","), + }, + }, + } + + event := &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: uuid.NewString(), + Module: agentEvent.module, + Timestamp: types.TimestampNow(), + EventLevel: WARN_EVENT_LEVEL, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } + + return &proto.Command{ + Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), + Type: proto.Command_NORMAL, + Data: &proto.Command_EventReport{ + EventReport: &eventsProto.EventReport{ + Events: []*eventsProto.Event{event}, + }, + }, + } +} diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go new file mode 100644 index 000000000..0340d130d --- /dev/null +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -0,0 +1,19 @@ +package events + +const ( + // Types + NGINX_EVENT_TYPE = "Nginx" + AGENT_EVENT_TYPE = "Agent" + + // Categories + STATUS_CATEGORY = "Status" + CONFIG_CATEGORY = "Config" + APP_PROTECT_CATEGORY = "AppProtect" + + // Event Levels + INFO_EVENT_LEVEL = "INFO" + DEBUG_EVENT_LEVEL = "DEBUG" + WARN_EVENT_LEVEL = "WARN" + ERROR_EVENT_LEVEL = "ERROR" + CRITICAL_EVENT_LEVEL = "CRITICAL" +) diff --git a/vendor/modules.txt b/vendor/modules.txt index 7fe7e4223..2e164272a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1122,6 +1122,7 @@ github.com/nbutton23/zxcvbn-go/utils/math ## explicit; go 1.21 github.com/nginx/agent/sdk/v2 github.com/nginx/agent/sdk/v2/agent/config +github.com/nginx/agent/sdk/v2/agent/events github.com/nginx/agent/sdk/v2/backoff github.com/nginx/agent/sdk/v2/checksum github.com/nginx/agent/sdk/v2/client From f5ba28ad51037137b07cfc401771c780106ab597 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Fri, 1 Sep 2023 16:01:40 +0100 Subject: [PATCH 02/20] WIP: move code about --- sdk/agent/events/meta.go | 22 +++++++++++++------ src/core/signals.go | 2 +- src/plugins/events_test.go | 2 +- .../nginx/agent/sdk/v2/agent/events/meta.go | 22 +++++++++++++------ .../nginx/agent/v2/src/core/signals.go | 2 +- .../nginx/agent/sdk/v2/agent/events/meta.go | 22 +++++++++++++------ .../nginx/agent/v2/src/core/signals.go | 2 +- .../nginx/agent/sdk/v2/agent/events/meta.go | 22 +++++++++++++------ 8 files changed, 64 insertions(+), 32 deletions(-) diff --git a/sdk/agent/events/meta.go b/sdk/agent/events/meta.go index ca2885dff..4ce12879f 100644 --- a/sdk/agent/events/meta.go +++ b/sdk/agent/events/meta.go @@ -46,25 +46,33 @@ func NewAgentEventMeta( } } -func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { +func (aem *AgentEventMeta) GetVersion() string { + return aem.version +} + +func (aem *AgentEventMeta) GetPid() string { + return aem.pid +} + +func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(agentEvent.message, agentEvent.version, agentEvent.pid, agentEvent.hostname), + Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", - Value: agentEvent.systemUuid, + Value: aem.systemUuid, }, { Name: "hostname", - Value: agentEvent.hostname, + Value: aem.hostname, }, { Name: "instance_group", - Value: agentEvent.instanceGroup, + Value: aem.instanceGroup, }, { Name: "system.tags", - Value: strings.Join(agentEvent.tags, ","), + Value: strings.Join(aem.tags, ","), }, }, } @@ -73,7 +81,7 @@ func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: uuid.NewString(), - Module: agentEvent.module, + Module: aem.module, Timestamp: types.TimestampNow(), EventLevel: WARN_EVENT_LEVEL, Type: AGENT_EVENT_TYPE, diff --git a/src/core/signals.go b/src/core/signals.go index 4640a532f..8d6e7e34a 100644 --- a/src/core/signals.go +++ b/src/core/signals.go @@ -47,7 +47,7 @@ func HandleSignals( loadedConfig.InstanceGroup, loadedConfig.Tags) - stopCmd := events.GenerateAgentStopEventCommand(event) + stopCmd := event.GenerateAgentStopEventCommand() log.Debugf("Sending agent stopped event: %v", stopCmd) if cmder == nil { diff --git a/src/plugins/events_test.go b/src/plugins/events_test.go index cbbfd7164..296d1ab8c 100644 --- a/src/plugins/events_test.go +++ b/src/plugins/events_test.go @@ -610,7 +610,7 @@ func TestGenerateAgentStopEvent(t *testing.T) { tt.conf.InstanceGroup, tt.conf.Tags, ) - agentStopCmd := events.GenerateAgentStopEventCommand(meta) + agentStopCmd := meta.GenerateAgentStopEventCommand() actualEvent := agentStopCmd.GetEventReport().Events[0] // assert metadata diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index ca2885dff..4ce12879f 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -46,25 +46,33 @@ func NewAgentEventMeta( } } -func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { +func (aem *AgentEventMeta) GetVersion() string { + return aem.version +} + +func (aem *AgentEventMeta) GetPid() string { + return aem.pid +} + +func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(agentEvent.message, agentEvent.version, agentEvent.pid, agentEvent.hostname), + Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", - Value: agentEvent.systemUuid, + Value: aem.systemUuid, }, { Name: "hostname", - Value: agentEvent.hostname, + Value: aem.hostname, }, { Name: "instance_group", - Value: agentEvent.instanceGroup, + Value: aem.instanceGroup, }, { Name: "system.tags", - Value: strings.Join(agentEvent.tags, ","), + Value: strings.Join(aem.tags, ","), }, }, } @@ -73,7 +81,7 @@ func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: uuid.NewString(), - Module: agentEvent.module, + Module: aem.module, Timestamp: types.TimestampNow(), EventLevel: WARN_EVENT_LEVEL, Type: AGENT_EVENT_TYPE, diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go index 4640a532f..8d6e7e34a 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go @@ -47,7 +47,7 @@ func HandleSignals( loadedConfig.InstanceGroup, loadedConfig.Tags) - stopCmd := events.GenerateAgentStopEventCommand(event) + stopCmd := event.GenerateAgentStopEventCommand() log.Debugf("Sending agent stopped event: %v", stopCmd) if cmder == nil { diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index ca2885dff..4ce12879f 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -46,25 +46,33 @@ func NewAgentEventMeta( } } -func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { +func (aem *AgentEventMeta) GetVersion() string { + return aem.version +} + +func (aem *AgentEventMeta) GetPid() string { + return aem.pid +} + +func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(agentEvent.message, agentEvent.version, agentEvent.pid, agentEvent.hostname), + Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", - Value: agentEvent.systemUuid, + Value: aem.systemUuid, }, { Name: "hostname", - Value: agentEvent.hostname, + Value: aem.hostname, }, { Name: "instance_group", - Value: agentEvent.instanceGroup, + Value: aem.instanceGroup, }, { Name: "system.tags", - Value: strings.Join(agentEvent.tags, ","), + Value: strings.Join(aem.tags, ","), }, }, } @@ -73,7 +81,7 @@ func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: uuid.NewString(), - Module: agentEvent.module, + Module: aem.module, Timestamp: types.TimestampNow(), EventLevel: WARN_EVENT_LEVEL, Type: AGENT_EVENT_TYPE, diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go index 4640a532f..8d6e7e34a 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go @@ -47,7 +47,7 @@ func HandleSignals( loadedConfig.InstanceGroup, loadedConfig.Tags) - stopCmd := events.GenerateAgentStopEventCommand(event) + stopCmd := event.GenerateAgentStopEventCommand() log.Debugf("Sending agent stopped event: %v", stopCmd) if cmder == nil { diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index ca2885dff..4ce12879f 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -46,25 +46,33 @@ func NewAgentEventMeta( } } -func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { +func (aem *AgentEventMeta) GetVersion() string { + return aem.version +} + +func (aem *AgentEventMeta) GetPid() string { + return aem.pid +} + +func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(agentEvent.message, agentEvent.version, agentEvent.pid, agentEvent.hostname), + Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", - Value: agentEvent.systemUuid, + Value: aem.systemUuid, }, { Name: "hostname", - Value: agentEvent.hostname, + Value: aem.hostname, }, { Name: "instance_group", - Value: agentEvent.instanceGroup, + Value: aem.instanceGroup, }, { Name: "system.tags", - Value: strings.Join(agentEvent.tags, ","), + Value: strings.Join(aem.tags, ","), }, }, } @@ -73,7 +81,7 @@ func GenerateAgentStopEventCommand(agentEvent *AgentEventMeta) *proto.Command { Metadata: &eventsProto.Metadata{ UUID: uuid.NewString(), CorrelationID: uuid.NewString(), - Module: agentEvent.module, + Module: aem.module, Timestamp: types.TimestampNow(), EventLevel: WARN_EVENT_LEVEL, Type: AGENT_EVENT_TYPE, From 77887a822cd4aa79720f3785d56e747a7bff4cc6 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Fri, 1 Sep 2023 16:08:22 +0100 Subject: [PATCH 03/20] WIP: fix code --- sdk/agent/events/meta_test.go | 26 ++++++++----------- src/plugins/events.go | 2 +- src/plugins/events_test.go | 13 +++++++--- .../nginx/agent/v2/src/plugins/events.go | 2 +- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/sdk/agent/events/meta_test.go b/sdk/agent/events/meta_test.go index 9f0195078..2d56b3e11 100644 --- a/sdk/agent/events/meta_test.go +++ b/sdk/agent/events/meta_test.go @@ -34,16 +34,16 @@ func TestNewAgentEventMeta(t *testing.T) { func TestGenerateAgentStopEventCommand(t *testing.T) { // Create a mock AgentEventMeta object - agentEvent := &AgentEventMeta{ - module: "agent-module", - version: "v2.0", - pid: "54321", - message: "Sample message: Version=%s, PID=%s, Hostname=%s", - hostname: "test-host", - systemUuid: "test-uuid", - instanceGroup: "group2", - tags: []string{"tag3", "tag4"}, - } + agentEvent := NewAgentEventMeta( + "agent-module", + "v2.0", + "54321", + "Sample message: Version=%s, PID=%s, Hostname=%s", + "test-host", + "test-uuid", + "group2", + []string{"tag3", "tag4"}, + ) expected := &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -64,14 +64,10 @@ func TestGenerateAgentStopEventCommand(t *testing.T) { }, } - // Generate the AgentStopEventCommand using the function - cmd := GenerateAgentStopEventCommand(agentEvent) + cmd := agentEvent.GenerateAgentStopEventCommand() - // Assert that the generated command is not nil assert.NotNil(t, cmd) - // You can add more specific assertions based on the expected structure and values of the generated command. - // For example, checking the UUIDs, message format, and other fields. assert.NotNil(t, cmd.Meta) assert.Equal(t, proto.Command_NORMAL, cmd.Type) assert.NotNil(t, cmd.Data) diff --git a/src/plugins/events.go b/src/plugins/events.go index cf90d629e..9c116982e 100644 --- a/src/plugins/events.go +++ b/src/plugins/events.go @@ -121,7 +121,7 @@ func (a *Events) sendAgentStartedEvent(msg *core.Message) { event := a.createAgentEvent( types.TimestampNow(), events.INFO_EVENT_LEVEL, - fmt.Sprintf(AGENT_START_MESSAGE, agentEventMeta.version, a.env.GetHostname(), agentEventMeta.pid), + fmt.Sprintf(AGENT_START_MESSAGE, agentEventMeta.GetVersion(), a.env.GetHostname(), agentEventMeta.GetPid()), uuid.NewString(), ) diff --git a/src/plugins/events_test.go b/src/plugins/events_test.go index 296d1ab8c..4406c210c 100644 --- a/src/plugins/events_test.go +++ b/src/plugins/events_test.go @@ -336,7 +336,16 @@ func TestActivityEvents_Process(t *testing.T) { }, { name: "test AgentStart message", - message: core.NewMessage(core.AgentStarted, &events.AgentEventMeta{version: "v0.0.1", pid: "75231"}), + message: core.NewMessage(core.AgentStarted, events.NewAgentEventMeta( + config.MODULE, + "v0.0.1", + "75231", + "nginx-agent v0.0.1 started on test-host with pid 75231", + "", + "", + "", + []string{}, + )), msgTopics: []string{ core.AgentStarted, core.Events, @@ -598,8 +607,6 @@ func TestGenerateAgentStopEvent(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { env := tutils.NewMockEnvironment() - // agentEventMeta := tt.expectedEvent.GetData().(*events.AgentEventMeta) - // message := tt.expectedEvent.GetData() meta := events.NewAgentEventMeta( config.MODULE, tt.agentVersion, diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go index cf90d629e..9c116982e 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go @@ -121,7 +121,7 @@ func (a *Events) sendAgentStartedEvent(msg *core.Message) { event := a.createAgentEvent( types.TimestampNow(), events.INFO_EVENT_LEVEL, - fmt.Sprintf(AGENT_START_MESSAGE, agentEventMeta.version, a.env.GetHostname(), agentEventMeta.pid), + fmt.Sprintf(AGENT_START_MESSAGE, agentEventMeta.GetVersion(), a.env.GetHostname(), agentEventMeta.GetPid()), uuid.NewString(), ) From 6ba6bc860dea5a33ec138c9cd32d8a63ded5ab6e Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Fri, 1 Sep 2023 16:09:07 +0100 Subject: [PATCH 04/20] local changes --- sdk/agent/events/meta.go | 2 +- src/plugins/events_test.go | 2 +- .../vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go | 2 +- .../vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go | 2 +- vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/agent/events/meta.go b/sdk/agent/events/meta.go index 4ce12879f..983b268cf 100644 --- a/sdk/agent/events/meta.go +++ b/sdk/agent/events/meta.go @@ -54,7 +54,7 @@ func (aem *AgentEventMeta) GetPid() string { return aem.pid } -func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { +func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ diff --git a/src/plugins/events_test.go b/src/plugins/events_test.go index 4406c210c..3817fec91 100644 --- a/src/plugins/events_test.go +++ b/src/plugins/events_test.go @@ -335,7 +335,7 @@ func TestActivityEvents_Process(t *testing.T) { }, }, { - name: "test AgentStart message", + name: "test AgentStart message", message: core.NewMessage(core.AgentStarted, events.NewAgentEventMeta( config.MODULE, "v0.0.1", diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 4ce12879f..983b268cf 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -54,7 +54,7 @@ func (aem *AgentEventMeta) GetPid() string { return aem.pid } -func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { +func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 4ce12879f..983b268cf 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -54,7 +54,7 @@ func (aem *AgentEventMeta) GetPid() string { return aem.pid } -func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { +func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 4ce12879f..983b268cf 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -54,7 +54,7 @@ func (aem *AgentEventMeta) GetPid() string { return aem.pid } -func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { +func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ From 92c2ddf774140045c9f39d89ad43e53cbb4e7cad Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Mon, 4 Sep 2023 16:00:43 +0100 Subject: [PATCH 05/20] wip: isolated load plugins --- main.go | 101 +--------------- sdk/agent/events/meta.go | 2 +- sdk/agent/events/meta_test.go | 40 +++++-- src/core/config/config.go | 2 + src/core/config/defaults.go | 1 + src/core/config/types.go | 1 + src/core/grpc_test.go | 24 ++-- src/plugins/commander.go | 16 +-- src/plugins/common.go | 109 ++++++++++++++++++ src/plugins/common_test.go | 24 ++++ src/plugins/dataplane_status.go | 4 +- src/plugins/dataplane_status_test.go | 8 +- src/plugins/events_test.go | 8 +- src/plugins/features.go | 4 +- src/plugins/registration.go | 5 +- src/plugins/registration_test.go | 8 +- .../nginx/agent/sdk/v2/agent/events/meta.go | 2 +- .../nginx/agent/v2/src/core/config/config.go | 2 + .../agent/v2/src/core/config/defaults.go | 1 + .../nginx/agent/v2/src/core/config/types.go | 1 + test/performance/plugins_test.go | 58 ---------- .../nginx/agent/sdk/v2/agent/events/meta.go | 2 +- .../nginx/agent/v2/src/core/config/config.go | 2 + .../agent/v2/src/core/config/defaults.go | 1 + .../nginx/agent/v2/src/core/config/types.go | 1 + .../nginx/agent/v2/src/plugins/commander.go | 16 +-- .../nginx/agent/v2/src/plugins/common.go | 109 ++++++++++++++++++ .../agent/v2/src/plugins/dataplane_status.go | 4 +- .../nginx/agent/v2/src/plugins/features.go | 4 +- .../agent/v2/src/plugins/registration.go | 5 +- .../nginx/agent/sdk/v2/agent/events/meta.go | 2 +- 31 files changed, 339 insertions(+), 228 deletions(-) create mode 100644 src/plugins/common.go create mode 100644 src/plugins/common_test.go create mode 100644 test/performance/vendor/github.com/nginx/agent/v2/src/plugins/common.go diff --git a/main.go b/main.go index a4723bdeb..001492e4e 100644 --- a/main.go +++ b/main.go @@ -14,15 +14,14 @@ import ( agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/sdk/v2/agent/events" - "github.com/nginx/agent/sdk/v2/client" + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" "github.com/nginx/agent/v2/src/core/logger" - "github.com/nginx/agent/v2/src/extensions" "github.com/nginx/agent/v2/src/plugins" - "github.com/google/uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -77,7 +76,7 @@ func main() { binary := core.NewNginxBinary(env, loadedConfig) - corePlugins, extensionPlugins := loadPlugins(commander, binary, env, reporter, loadedConfig) + corePlugins, extensionPlugins := plugins.LoadPlugins(commander, binary, env, reporter, loadedConfig) pipe := core.InitializePipe(ctx, corePlugins, extensionPlugins, agent_config.DefaultPluginSize) @@ -100,97 +99,3 @@ func main() { log.Fatal(err) } } - -func loadPlugins(commander client.Commander, binary *core.NginxBinaryType, env *core.EnvironmentType, reporter client.MetricReporter, loadedConfig *config.Config) ([]core.Plugin, []core.ExtensionPlugin) { - var corePlugins []core.Plugin - var extensionPlugins []core.ExtensionPlugin - - if commander != nil { - corePlugins = append(corePlugins, - plugins.NewCommander(commander, loadedConfig), - ) - - if loadedConfig.IsFeatureEnabled(agent_config.FeatureFileWatcher) { - corePlugins = append(corePlugins, - plugins.NewFileWatcher(loadedConfig, env), - plugins.NewFileWatchThrottle(), - ) - } - } - - if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsSender) && reporter != nil { - corePlugins = append(corePlugins, - plugins.NewMetricsSender(reporter), - ) - } - - corePlugins = append(corePlugins, - plugins.NewConfigReader(loadedConfig), - plugins.NewNginx(commander, binary, env, loadedConfig), - plugins.NewExtensions(loadedConfig, env), - plugins.NewFeatures(commander, loadedConfig, env, binary, version), - ) - - if loadedConfig.IsFeatureEnabled(agent_config.FeatureRegistration) { - corePlugins = append(corePlugins, plugins.NewOneTimeRegistration(loadedConfig, binary, env, sdkGRPC.NewMessageMeta(uuid.NewString()), version)) - } - - if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsCollection) || - (len(loadedConfig.Nginx.NginxCountingSocket) > 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxCounting)) { - corePlugins = append(corePlugins, plugins.NewMetrics(loadedConfig, env, binary)) - } - - if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsThrottle) { - corePlugins = append(corePlugins, plugins.NewMetricsThrottle(loadedConfig, env)) - } - - if loadedConfig.IsFeatureEnabled(agent_config.FeatureDataPlaneStatus) { - corePlugins = append(corePlugins, plugins.NewDataPlaneStatus(loadedConfig, sdkGRPC.NewMessageMeta(uuid.NewString()), binary, env, version)) - } - - if loadedConfig.IsFeatureEnabled(agent_config.FeatureProcessWatcher) { - corePlugins = append(corePlugins, plugins.NewProcessWatcher(env, binary)) - } - - if loadedConfig.IsFeatureEnabled(agent_config.FeatureActivityEvents) { - corePlugins = append(corePlugins, plugins.NewEvents(loadedConfig, env, sdkGRPC.NewMessageMeta(uuid.NewString()), binary)) - } - - if loadedConfig.AgentAPI.Port != 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureAgentAPI) { - corePlugins = append(corePlugins, plugins.NewAgentAPI(loadedConfig, env, binary)) - } else { - log.Info("Agent API not configured") - } - - if len(loadedConfig.Nginx.NginxCountingSocket) > 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxCounting) { - corePlugins = append(corePlugins, plugins.NewNginxCounter(loadedConfig, binary, env)) - } - - if loadedConfig.Extensions != nil && len(loadedConfig.Extensions) > 0 { - for _, extension := range loadedConfig.Extensions { - switch { - case extension == agent_config.AdvancedMetricsExtensionPlugin: - advancedMetricsExtensionPlugin := extensions.NewAdvancedMetrics(env, loadedConfig, config.Viper.Get(agent_config.AdvancedMetricsExtensionPluginConfigKey)) - extensionPlugins = append(extensionPlugins, advancedMetricsExtensionPlugin) - case extension == agent_config.NginxAppProtectExtensionPlugin: - nginxAppProtectExtensionPlugin, err := extensions.NewNginxAppProtect(loadedConfig, env, config.Viper.Get(agent_config.NginxAppProtectExtensionPluginConfigKey)) - if err != nil { - log.Errorf("Unable to load the Nginx App Protect plugin due to the following error: %v", err) - } else { - extensionPlugins = append(extensionPlugins, nginxAppProtectExtensionPlugin) - } - case extension == agent_config.NginxAppProtectMonitoringExtensionPlugin: - nginxAppProtectMonitoringExtensionPlugin, err := extensions.NewNAPMonitoring(env, loadedConfig, config.Viper.Get(agent_config.NginxAppProtectMonitoringExtensionPluginConfigKey)) - if err != nil { - log.Errorf("Unable to load the Nginx App Protect Monitoring plugin due to the following error: %v", err) - } else { - extensionPlugins = append(extensionPlugins, nginxAppProtectMonitoringExtensionPlugin) - } - default: - log.Warnf("unknown extension configured: %s", extension) - } - } - } - - return corePlugins, extensionPlugins -} diff --git a/sdk/agent/events/meta.go b/sdk/agent/events/meta.go index 983b268cf..a2a9b10e4 100644 --- a/sdk/agent/events/meta.go +++ b/sdk/agent/events/meta.go @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", diff --git a/sdk/agent/events/meta_test.go b/sdk/agent/events/meta_test.go index 2d56b3e11..a9e91308a 100644 --- a/sdk/agent/events/meta_test.go +++ b/sdk/agent/events/meta_test.go @@ -1,9 +1,12 @@ package events import ( + "fmt" + "strings" "testing" "github.com/nginx/agent/sdk/v2/proto" + commonProto "github.com/nginx/agent/sdk/v2/proto/common" eventsProto "github.com/nginx/agent/sdk/v2/proto/events" "github.com/stretchr/testify/assert" ) @@ -33,18 +36,39 @@ func TestNewAgentEventMeta(t *testing.T) { } func TestGenerateAgentStopEventCommand(t *testing.T) { - // Create a mock AgentEventMeta object agentEvent := NewAgentEventMeta( "agent-module", "v2.0", "54321", - "Sample message: Version=%s, PID=%s, Hostname=%s", + "agent-module", "test-host", "test-uuid", "group2", []string{"tag3", "tag4"}, ) + expectedActivityEvent:= &eventsProto.ActivityEvent{ + Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", "agent-module", "v2.0", "54321", "test-host"), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: "test-uuid", + }, + { + Name: "hostname", + Value: "test-host", + }, + { + Name: "instance_group", + Value: "group2", + }, + { + Name: "system.tags", + Value: strings.Join([]string{"tag3", "tag4"}, ","), + }, + }, + } + expected := &eventsProto.EventReport{ Events: []*eventsProto.Event{ { @@ -55,21 +79,17 @@ func TestGenerateAgentStopEventCommand(t *testing.T) { EventLevel: ERROR_EVENT_LEVEL, }, Data: &eventsProto.Event_ActivityEvent{ - ActivityEvent: &eventsProto.ActivityEvent{ - Message: "failed to rollback nginx config on test-host", - Dimensions: nil, - }, + ActivityEvent: expectedActivityEvent, }, }, }, } cmd := agentEvent.GenerateAgentStopEventCommand() - assert.NotNil(t, cmd) - assert.NotNil(t, cmd.Meta) assert.Equal(t, proto.Command_NORMAL, cmd.Type) - assert.NotNil(t, cmd.Data) - assert.Equal(t, expected, cmd.GetData()) + assert.NotNil(t, cmd.GetData()) + + assert.Equal(t, expected.GetEvents()[0].GetData(), cmd.GetData().(*proto.Command_EventReport).EventReport.GetEvents()[0].GetData()) } diff --git a/src/core/config/config.go b/src/core/config/config.go index 4f6983717..84dd39582 100644 --- a/src/core/config/config.go +++ b/src/core/config/config.go @@ -55,6 +55,7 @@ var Viper = viper.NewWithOptions(viper.KeyDelimiter(agent_config.KeyDelimiter)) func SetVersion(version, commit string) { ROOT_COMMAND.Version = version + "-" + commit + Viper.SetDefault(VersionKey, version) } func Execute() error { @@ -181,6 +182,7 @@ func GetConfig(clientId string) (*Config, error) { } config := &Config{ + Version: Viper.GetString(VersionKey), Path: Viper.GetString(ConfigPathKey), DynamicConfigPath: Viper.GetString(DynamicConfigPathKey), ClientID: clientId, diff --git a/src/core/config/defaults.go b/src/core/config/defaults.go index a4fcfddf5..de88138c1 100644 --- a/src/core/config/defaults.go +++ b/src/core/config/defaults.go @@ -104,6 +104,7 @@ const ( ConfigPathKey = "path" DynamicConfigPathKey = "dynamic-config-path" + VersionKey = "version" CloudAccountIdKey = "cloudaccountid" LocationKey = "location" DisplayNameKey = "display_name" diff --git a/src/core/config/types.go b/src/core/config/types.go index 57497ebe6..a7ba6a7fd 100644 --- a/src/core/config/types.go +++ b/src/core/config/types.go @@ -14,6 +14,7 @@ import ( ) type Config struct { + Version string Path string `yaml:"-"` DynamicConfigPath string `yaml:"-"` ClientID string `mapstructure:"agent_id" yaml:"-"` diff --git a/src/core/grpc_test.go b/src/core/grpc_test.go index ea07731f1..5663a6c01 100644 --- a/src/core/grpc_test.go +++ b/src/core/grpc_test.go @@ -9,19 +9,14 @@ import ( ) func TestCreateGrpcClients(t *testing.T) { - // Create a mock configuration with proper settings loadedConfig := &config.Config{ TLS: config.TLSConfig{ Enable: true, - Cert: "cert.pem", - Key: "key.pem", - Ca: "ca.pem", SkipVerify: false, }, Server: config.Server{ - Metrics: "metrics-server", - Command: "command-server", - Target: "grpc-server", + GrpcPort: 6789, + Host: "192.0.2.4", }, } @@ -33,24 +28,21 @@ func TestCreateGrpcClients(t *testing.T) { assert.NotNil(t, controller) assert.NotNil(t, commander) assert.NotNil(t, reporter) - - // Additional assertions can be added to test the client configurations - // For example, you can check if the dial options are set correctly. } func TestSetDialOptions(t *testing.T) { - // Create a mock configuration with proper settings loadedConfig := &config.Config{ + TLS: config.TLSConfig{ + Enable: true, + SkipVerify: false, + }, Server: config.Server{ - Token: "your-token", + GrpcPort: 67890, + Host: "192.0.2.5", }, } dialOptions := setDialOptions(loadedConfig) - // Assert that the dial options are not empty and contain expected options. assert.NotEmpty(t, dialOptions) - - // You can add more specific assertions based on your expected dial options. - // For example, checking if grpc.WithUserAgent is set, or other options. } diff --git a/src/plugins/commander.go b/src/plugins/commander.go index 994c952a1..8ce701833 100644 --- a/src/plugins/commander.go +++ b/src/plugins/commander.go @@ -100,7 +100,7 @@ func (c *Commander) agentBackoff(agentConfig *proto.AgentConfig) { } func (c *Commander) agentRegistered(cmd *proto.Command) { - switch commandData := cmd.Data.(type) { + switch commandData := cmd.GetData().(type) { case *proto.Command_AgentConnectResponse: log.Infof("config command %v", commandData) @@ -112,7 +112,7 @@ func (c *Commander) agentRegistered(cmd *proto.Command) { } default: - log.Debugf("unhandled command: %T", cmd.Data) + log.Debugf("unhandled command: %T", cmd.GetData()) } } @@ -152,24 +152,24 @@ func (c *Commander) dispatchLoop() { log.Debugf("Command msg from data plane: %v", cmd) var topic string - switch cmd.Data.(type) { + switch cmd.GetData().(type) { case *proto.Command_NginxConfig, *proto.Command_NginxConfigResponse: topic = core.CommNginxConfig case *proto.Command_AgentConnectRequest, *proto.Command_AgentConnectResponse: topic = core.AgentConnected case *proto.Command_AgentConfigRequest, *proto.Command_AgentConfig: - log.Debugf("agent config %T command data type received and ignored", cmd.Data) + log.Debugf("agent config %T command data type received and ignored", cmd.GetData()) topic = core.AgentConfig case *proto.Command_CmdStatus: - data := cmd.Data.(*proto.Command_CmdStatus) + data := cmd.GetData().(*proto.Command_CmdStatus) if data.CmdStatus.Status != proto.CommandStatusResponse_CMD_OK { - log.Debugf("command status %T :: %+v", cmd.Data, cmd.Data) + log.Debugf("command status %T :: %+v", cmd.GetData(), cmd.GetData()) } topic = core.UNKNOWN continue default: - if cmd.Data != nil { - log.Infof("unknown %T command data type received", cmd.Data) + if cmd.GetData() != nil { + log.Infof("unknown %T command data type received", cmd.GetData()) } topic = core.UNKNOWN continue diff --git a/src/plugins/common.go b/src/plugins/common.go new file mode 100644 index 000000000..beb762146 --- /dev/null +++ b/src/plugins/common.go @@ -0,0 +1,109 @@ +package plugins + +import ( + "github.com/nginx/agent/sdk/v2/client" + "github.com/nginx/agent/v2/src/core" + "github.com/nginx/agent/v2/src/core/config" + "github.com/nginx/agent/v2/src/extensions" + log "github.com/sirupsen/logrus" + + agent_config "github.com/nginx/agent/sdk/v2/agent/config" + + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + + "github.com/google/uuid" +) + +func LoadPlugins(commander client.Commander, binary core.NginxBinary, env core.Environment, reporter client.MetricReporter, loadedConfig *config.Config) ([]core.Plugin, []core.ExtensionPlugin) { + var corePlugins []core.Plugin + var extensionPlugins []core.ExtensionPlugin + + if commander != nil { + corePlugins = append(corePlugins, + NewCommander(commander, loadedConfig), + ) + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureFileWatcher) { + corePlugins = append(corePlugins, + NewFileWatcher(loadedConfig, env), + NewFileWatchThrottle(), + ) + } + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsSender) && reporter != nil { + corePlugins = append(corePlugins, + NewMetricsSender(reporter), + ) + } + + corePlugins = append(corePlugins, + NewConfigReader(loadedConfig), + NewNginx(commander, binary, env, loadedConfig), + NewExtensions(loadedConfig, env), + NewFeatures(commander, loadedConfig, env, binary, loadedConfig.Version), + ) + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureRegistration) { + corePlugins = append(corePlugins, NewOneTimeRegistration(loadedConfig, binary, env, sdkGRPC.NewMessageMeta(uuid.NewString()))) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsCollection) || + (len(loadedConfig.Nginx.NginxCountingSocket) > 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxCounting)) { + corePlugins = append(corePlugins, NewMetrics(loadedConfig, env, binary)) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsThrottle) { + corePlugins = append(corePlugins, NewMetricsThrottle(loadedConfig, env)) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureDataPlaneStatus) { + corePlugins = append(corePlugins, NewDataPlaneStatus(loadedConfig, sdkGRPC.NewMessageMeta(uuid.NewString()), binary, env)) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureProcessWatcher) { + corePlugins = append(corePlugins, NewProcessWatcher(env, binary)) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureActivityEvents) { + corePlugins = append(corePlugins, NewEvents(loadedConfig, env, sdkGRPC.NewMessageMeta(uuid.NewString()), binary)) + } + + if loadedConfig.AgentAPI.Port != 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureAgentAPI) { + corePlugins = append(corePlugins, NewAgentAPI(loadedConfig, env, binary)) + } else { + log.Info("Agent API not configured") + } + + if len(loadedConfig.Nginx.NginxCountingSocket) > 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxCounting) { + corePlugins = append(corePlugins, NewNginxCounter(loadedConfig, binary, env)) + } + + if loadedConfig.Extensions != nil && len(loadedConfig.Extensions) > 0 { + for _, extension := range loadedConfig.Extensions { + switch { + case extension == agent_config.AdvancedMetricsExtensionPlugin: + advancedMetricsExtensionPlugin := extensions.NewAdvancedMetrics(env, loadedConfig, config.Viper.Get(agent_config.AdvancedMetricsExtensionPluginConfigKey)) + extensionPlugins = append(extensionPlugins, advancedMetricsExtensionPlugin) + case extension == agent_config.NginxAppProtectExtensionPlugin: + nginxAppProtectExtensionPlugin, err := extensions.NewNginxAppProtect(loadedConfig, env, config.Viper.Get(agent_config.NginxAppProtectExtensionPluginConfigKey)) + if err != nil { + log.Errorf("Unable to load the Nginx App Protect plugin due to the following error: %v", err) + } else { + extensionPlugins = append(extensionPlugins, nginxAppProtectExtensionPlugin) + } + case extension == agent_config.NginxAppProtectMonitoringExtensionPlugin: + nginxAppProtectMonitoringExtensionPlugin, err := extensions.NewNAPMonitoring(env, loadedConfig, config.Viper.Get(agent_config.NginxAppProtectMonitoringExtensionPluginConfigKey)) + if err != nil { + log.Errorf("Unable to load the Nginx App Protect Monitoring plugin due to the following error: %v", err) + } else { + extensionPlugins = append(extensionPlugins, nginxAppProtectMonitoringExtensionPlugin) + } + default: + log.Warnf("unknown extension configured: %s", extension) + } + } + } + + return corePlugins, extensionPlugins +} diff --git a/src/plugins/common_test.go b/src/plugins/common_test.go new file mode 100644 index 000000000..0e1ce2b69 --- /dev/null +++ b/src/plugins/common_test.go @@ -0,0 +1,24 @@ +package plugins + +import ( + "testing" + + "github.com/nginx/agent/v2/src/core/config" + tutils "github.com/nginx/agent/v2/test/utils" + "github.com/stretchr/testify/assert" +) + +func TestLoadPlugins(t *testing.T) { + // Create mock objects or use testing stubs for dependencies like 'commander', 'binary', 'env', 'reporter', 'loadedConfig', etc. + binary := tutils.NewMockNginxBinary() + env := tutils.GetMockEnvWithProcess() + cmdr := tutils.NewMockCommandClient() + reporter := tutils.NewMockMetricsReportClient() + loadedConfig := &config.Config{ /* Set loadedConfig fields accordingly */ } + + corePlugins, extensionPlugins := LoadPlugins(cmdr, binary, env, reporter, loadedConfig) + + assert.NotNil(t, corePlugins) + assert.Len(t, corePlugins, 5) + assert.Len(t, extensionPlugins, 0) +} diff --git a/src/plugins/dataplane_status.go b/src/plugins/dataplane_status.go index 2160e50e7..d1aef6ae7 100644 --- a/src/plugins/dataplane_status.go +++ b/src/plugins/dataplane_status.go @@ -48,7 +48,7 @@ const ( defaultMinInterval = time.Second * 30 ) -func NewDataPlaneStatus(config *config.Config, meta *proto.Metadata, binary core.NginxBinary, env core.Environment, version string) *DataPlaneStatus { +func NewDataPlaneStatus(config *config.Config, meta *proto.Metadata, binary core.NginxBinary, env core.Environment) *DataPlaneStatus { log.Tracef("Dataplane status interval %s", config.Dataplane.Status.PollInterval) pollInt := config.Dataplane.Status.PollInterval if pollInt < defaultMinInterval { @@ -62,7 +62,7 @@ func NewDataPlaneStatus(config *config.Config, meta *proto.Metadata, binary core meta: meta, binary: binary, env: env, - version: version, + version: config.Version, tags: &config.Tags, configDirs: config.ConfigDirs, reportInterval: config.Dataplane.Status.ReportInterval, diff --git a/src/plugins/dataplane_status_test.go b/src/plugins/dataplane_status_test.go index b66e7bd55..5fce85134 100644 --- a/src/plugins/dataplane_status_test.go +++ b/src/plugins/dataplane_status_test.go @@ -176,7 +176,7 @@ func TestDataPlaneStatus(t *testing.T) { Tags: []string{}, } - dataPlaneStatus := NewDataPlaneStatus(config, grpc.NewMessageMeta(uuid.New().String()), binary, env, "") + dataPlaneStatus := NewDataPlaneStatus(config, grpc.NewMessageMeta(uuid.New().String()), binary, env) messagePipe := core.NewMockMessagePipe(context.Background()) err := messagePipe.Register(10, []core.Plugin{dataPlaneStatus}, []core.ExtensionPlugin{}) @@ -273,7 +273,7 @@ func TestDPSSyncAgentConfigChange(t *testing.T) { defer cleanupFunc() // Setup data plane status and mock pipeline - dataPlaneStatus := NewDataPlaneStatus(tc.config, grpc.NewMessageMeta(uuid.New().String()), binary, env, "") + dataPlaneStatus := NewDataPlaneStatus(tc.config, grpc.NewMessageMeta(uuid.New().String()), binary, env) messagePipe := core.NewMockMessagePipe(context.Background()) err = messagePipe.Register(10, []core.Plugin{dataPlaneStatus}, []core.ExtensionPlugin{}) @@ -350,7 +350,7 @@ func TestDPSSyncNAPDetails(t *testing.T) { for _, tc := range testCases { t.Run(tc.testName, func(t *testing.T) { // Setup DataPlaneStatus - dataPlaneStatus := NewDataPlaneStatus(config, grpc.NewMessageMeta(uuid.New().String()), binary, env, "") + dataPlaneStatus := NewDataPlaneStatus(config, grpc.NewMessageMeta(uuid.New().String()), binary, env) dataPlaneStatus.softwareDetails[agent_config.NginxAppProtectExtensionPlugin] = &proto.DataplaneSoftwareDetails{Data: tc.initialNAPDetails} defer dataPlaneStatus.Close() @@ -416,7 +416,7 @@ func TestDataPlaneSubscriptions(t *testing.T) { Tags: []string{}, } - dataPlaneStatus := NewDataPlaneStatus(config, grpc.NewMessageMeta(uuid.New().String()), binary, env, "") + dataPlaneStatus := NewDataPlaneStatus(config, grpc.NewMessageMeta(uuid.New().String()), binary, env) assert.Equal(t, expectedSubscriptions, dataPlaneStatus.Subscriptions()) } diff --git a/src/plugins/events_test.go b/src/plugins/events_test.go index 3817fec91..cf491e122 100644 --- a/src/plugins/events_test.go +++ b/src/plugins/events_test.go @@ -611,14 +611,14 @@ func TestGenerateAgentStopEvent(t *testing.T) { config.MODULE, tt.agentVersion, tt.pid, - "", + "nginx-agent", env.GetHostname(), env.GetSystemUUID(), tt.conf.InstanceGroup, tt.conf.Tags, ) agentStopCmd := meta.GenerateAgentStopEventCommand() - actualEvent := agentStopCmd.GetEventReport().Events[0] + actualEvent := agentStopCmd.GetEventReport().GetEvents()[0] // assert metadata assert.Equal(t, tt.expectedEvent.Metadata.Module, actualEvent.Metadata.Module) @@ -627,8 +627,8 @@ func TestGenerateAgentStopEvent(t *testing.T) { assert.Equal(t, tt.expectedEvent.Metadata.EventLevel, actualEvent.Metadata.EventLevel) // assert activity event - assert.Equal(t, tt.expectedEvent.GetActivityEvent().Message, actualEvent.GetActivityEvent().Message) - assert.Equal(t, tt.expectedEvent.GetActivityEvent().Dimensions, actualEvent.GetActivityEvent().Dimensions) + assert.Equal(t, tt.expectedEvent.GetActivityEvent().GetMessage(), actualEvent.GetActivityEvent().GetMessage()) + assert.Equal(t, tt.expectedEvent.GetActivityEvent().GetDimensions(), actualEvent.GetActivityEvent().GetDimensions()) }) } } diff --git a/src/plugins/features.go b/src/plugins/features.go index 7a17686a3..51f1867a2 100644 --- a/src/plugins/features.go +++ b/src/plugins/features.go @@ -210,7 +210,7 @@ func (f *Features) enableRegistrationFeature(data string) []core.Plugin { } f.conf = conf - registration := NewOneTimeRegistration(f.conf, f.binary, f.env, sdkGRPC.NewMessageMeta(uuid.NewString()), f.version) + registration := NewOneTimeRegistration(f.conf, f.binary, f.env, sdkGRPC.NewMessageMeta(uuid.NewString())) return []core.Plugin{registration} } @@ -225,7 +225,7 @@ func (f *Features) enableDataPlaneStatusFeature(data string) []core.Plugin { } f.conf = conf - dataPlaneStatus := NewDataPlaneStatus(f.conf, sdkGRPC.NewMessageMeta(uuid.NewString()), f.binary, f.env, f.version) + dataPlaneStatus := NewDataPlaneStatus(f.conf, sdkGRPC.NewMessageMeta(uuid.NewString()), f.binary, f.env) return []core.Plugin{dataPlaneStatus} } diff --git a/src/plugins/registration.go b/src/plugins/registration.go index 8d94b736d..c57209fc0 100644 --- a/src/plugins/registration.go +++ b/src/plugins/registration.go @@ -49,13 +49,12 @@ func NewOneTimeRegistration( binary core.NginxBinary, env core.Environment, meta *proto.Metadata, - version string, ) *OneTimeRegistration { // this might be slow so do on startup - host := env.NewHostInfo(version, &config.Tags, config.ConfigDirs, true) + host := env.NewHostInfo(config.Version, &config.Tags, config.ConfigDirs, true) return &OneTimeRegistration{ tags: &config.Tags, - agentVersion: version, + agentVersion: config.Version, meta: meta, config: config, env: env, diff --git a/src/plugins/registration_test.go b/src/plugins/registration_test.go index ab0360d27..84c05da74 100644 --- a/src/plugins/registration_test.go +++ b/src/plugins/registration_test.go @@ -45,7 +45,7 @@ func TestRegistration_Process(t *testing.T) { Extensions: []string{agent_config.NginxAppProtectExtensionPlugin}, } - pluginUnderTest := NewOneTimeRegistration(cfg, binary, env, &proto.Metadata{}, "0.0.0") + pluginUnderTest := NewOneTimeRegistration(cfg, binary, env, &proto.Metadata{}) pluginUnderTest.dataplaneSoftwareDetails[agent_config.NginxAppProtectExtensionPlugin] = &proto.DataplaneSoftwareDetails{ Data: testNAPDetailsActive, } @@ -77,7 +77,7 @@ func TestRegistration_areDataplaneSoftwareDetailsReady(t *testing.T) { conf := tutils.GetMockAgentConfig() conf.Extensions = []string{agent_config.NginxAppProtectExtensionPlugin} - pluginUnderTest := NewOneTimeRegistration(conf, nil, tutils.GetMockEnv(), nil, "") + pluginUnderTest := NewOneTimeRegistration(conf, nil, tutils.GetMockEnv(), nil) softwareDetails := make(map[string]*proto.DataplaneSoftwareDetails) softwareDetails[agent_config.NginxAppProtectExtensionPlugin] = &proto.DataplaneSoftwareDetails{} pluginUnderTest.dataplaneSoftwareDetails = softwareDetails @@ -86,13 +86,13 @@ func TestRegistration_areDataplaneSoftwareDetailsReady(t *testing.T) { } func TestRegistration_Subscriptions(t *testing.T) { - pluginUnderTest := NewOneTimeRegistration(tutils.GetMockAgentConfig(), nil, tutils.GetMockEnv(), nil, "") + pluginUnderTest := NewOneTimeRegistration(tutils.GetMockAgentConfig(), nil, tutils.GetMockEnv(), nil) assert.Equal(t, []string{core.RegistrationCompletedTopic, core.DataplaneSoftwareDetailsUpdated}, pluginUnderTest.Subscriptions()) } func TestRegistration_Info(t *testing.T) { - pluginUnderTest := NewOneTimeRegistration(tutils.GetMockAgentConfig(), nil, tutils.GetMockEnv(), nil, "") + pluginUnderTest := NewOneTimeRegistration(tutils.GetMockAgentConfig(), nil, tutils.GetMockEnv(), nil) assert.Equal(t, "registration", pluginUnderTest.Info().Name()) } diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 983b268cf..a2a9b10e4 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/config.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/config.go index 4f6983717..84dd39582 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/config.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/config.go @@ -55,6 +55,7 @@ var Viper = viper.NewWithOptions(viper.KeyDelimiter(agent_config.KeyDelimiter)) func SetVersion(version, commit string) { ROOT_COMMAND.Version = version + "-" + commit + Viper.SetDefault(VersionKey, version) } func Execute() error { @@ -181,6 +182,7 @@ func GetConfig(clientId string) (*Config, error) { } config := &Config{ + Version: Viper.GetString(VersionKey), Path: Viper.GetString(ConfigPathKey), DynamicConfigPath: Viper.GetString(DynamicConfigPathKey), ClientID: clientId, diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go index a4fcfddf5..de88138c1 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go @@ -104,6 +104,7 @@ const ( ConfigPathKey = "path" DynamicConfigPathKey = "dynamic-config-path" + VersionKey = "version" CloudAccountIdKey = "cloudaccountid" LocationKey = "location" DisplayNameKey = "display_name" diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/types.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/types.go index 57497ebe6..a7ba6a7fd 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/types.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/config/types.go @@ -14,6 +14,7 @@ import ( ) type Config struct { + Version string Path string `yaml:"-"` DynamicConfigPath string `yaml:"-"` ClientID string `mapstructure:"agent_id" yaml:"-"` diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index 78e36b6d4..408c43ab0 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -125,61 +125,3 @@ func BenchmarkPluginOneTimeRegistration(b *testing.B) { cancel() <-pipelineDone } - -func BenchmarkPluginOneTimeRegistration(b *testing.B) { - var pluginsUnderTest []core.Plugin - - ctx, cancel := context.WithCancel(context.Background()) - pipelineDone := make(chan bool) - - config := config.Config{Nginx: config.Nginx{Debug: true}} - - processID := "12345" - detailsMap := map[string]*proto.NginxDetails{ - processID: { - ProcessPath: "/path/to/nginx", - NginxId: processID, - }, - } - - binary := utils.NewMockNginxBinary() - binary.On("GetNginxDetailsMapFromProcesses", mock.Anything).Return(detailsMap) - binary.On("GetNginxIDForProcess", mock.Anything).Return(processID) - binary.On("GetNginxDetailsFromProcess", mock.Anything).Return(detailsMap[processID]) - binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) - - env := utils.NewMockEnvironment() - env.Mock.On("NewHostInfo", mock.Anything, mock.Anything, mock.Anything).Return(&proto.HostInfo{ - Hostname: "test-host", - }) - env.Mock.On("Processes", mock.Anything).Return([]*core.Process{ - { - Name: processID, - IsMaster: true, - }, - }) - - meta := proto.Metadata{} - version := "1234" - - messagePipe := core.NewMessagePipe(ctx) - for n := 0; n < b.N; n++ { - pluginsUnderTest = append(pluginsUnderTest, plugins.NewOneTimeRegistration(&config, binary, env, &meta, version)) - } - - err := messagePipe.Register(b.N, pluginsUnderTest, []core.ExtensionPlugin{}) - assert.NoError(b, err) - - go func() { - messagePipe.Run() - pipelineDone <- true - }() - - for n := 0; n < b.N; n++ { - messagePipe.Process(core.NewMessage(core.UNKNOWN, n)) - time.Sleep(200 * time.Millisecond) // for the above call being asynchronous - } - - cancel() - <-pipelineDone -} diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 983b268cf..a2a9b10e4 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go index 4f6983717..84dd39582 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go @@ -55,6 +55,7 @@ var Viper = viper.NewWithOptions(viper.KeyDelimiter(agent_config.KeyDelimiter)) func SetVersion(version, commit string) { ROOT_COMMAND.Version = version + "-" + commit + Viper.SetDefault(VersionKey, version) } func Execute() error { @@ -181,6 +182,7 @@ func GetConfig(clientId string) (*Config, error) { } config := &Config{ + Version: Viper.GetString(VersionKey), Path: Viper.GetString(ConfigPathKey), DynamicConfigPath: Viper.GetString(DynamicConfigPathKey), ClientID: clientId, diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go index a4fcfddf5..de88138c1 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go @@ -104,6 +104,7 @@ const ( ConfigPathKey = "path" DynamicConfigPathKey = "dynamic-config-path" + VersionKey = "version" CloudAccountIdKey = "cloudaccountid" LocationKey = "location" DisplayNameKey = "display_name" diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/types.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/types.go index 57497ebe6..a7ba6a7fd 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/types.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/types.go @@ -14,6 +14,7 @@ import ( ) type Config struct { + Version string Path string `yaml:"-"` DynamicConfigPath string `yaml:"-"` ClientID string `mapstructure:"agent_id" yaml:"-"` diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/commander.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/commander.go index 994c952a1..8ce701833 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/commander.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/commander.go @@ -100,7 +100,7 @@ func (c *Commander) agentBackoff(agentConfig *proto.AgentConfig) { } func (c *Commander) agentRegistered(cmd *proto.Command) { - switch commandData := cmd.Data.(type) { + switch commandData := cmd.GetData().(type) { case *proto.Command_AgentConnectResponse: log.Infof("config command %v", commandData) @@ -112,7 +112,7 @@ func (c *Commander) agentRegistered(cmd *proto.Command) { } default: - log.Debugf("unhandled command: %T", cmd.Data) + log.Debugf("unhandled command: %T", cmd.GetData()) } } @@ -152,24 +152,24 @@ func (c *Commander) dispatchLoop() { log.Debugf("Command msg from data plane: %v", cmd) var topic string - switch cmd.Data.(type) { + switch cmd.GetData().(type) { case *proto.Command_NginxConfig, *proto.Command_NginxConfigResponse: topic = core.CommNginxConfig case *proto.Command_AgentConnectRequest, *proto.Command_AgentConnectResponse: topic = core.AgentConnected case *proto.Command_AgentConfigRequest, *proto.Command_AgentConfig: - log.Debugf("agent config %T command data type received and ignored", cmd.Data) + log.Debugf("agent config %T command data type received and ignored", cmd.GetData()) topic = core.AgentConfig case *proto.Command_CmdStatus: - data := cmd.Data.(*proto.Command_CmdStatus) + data := cmd.GetData().(*proto.Command_CmdStatus) if data.CmdStatus.Status != proto.CommandStatusResponse_CMD_OK { - log.Debugf("command status %T :: %+v", cmd.Data, cmd.Data) + log.Debugf("command status %T :: %+v", cmd.GetData(), cmd.GetData()) } topic = core.UNKNOWN continue default: - if cmd.Data != nil { - log.Infof("unknown %T command data type received", cmd.Data) + if cmd.GetData() != nil { + log.Infof("unknown %T command data type received", cmd.GetData()) } topic = core.UNKNOWN continue diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/common.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/common.go new file mode 100644 index 000000000..beb762146 --- /dev/null +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/common.go @@ -0,0 +1,109 @@ +package plugins + +import ( + "github.com/nginx/agent/sdk/v2/client" + "github.com/nginx/agent/v2/src/core" + "github.com/nginx/agent/v2/src/core/config" + "github.com/nginx/agent/v2/src/extensions" + log "github.com/sirupsen/logrus" + + agent_config "github.com/nginx/agent/sdk/v2/agent/config" + + sdkGRPC "github.com/nginx/agent/sdk/v2/grpc" + + "github.com/google/uuid" +) + +func LoadPlugins(commander client.Commander, binary core.NginxBinary, env core.Environment, reporter client.MetricReporter, loadedConfig *config.Config) ([]core.Plugin, []core.ExtensionPlugin) { + var corePlugins []core.Plugin + var extensionPlugins []core.ExtensionPlugin + + if commander != nil { + corePlugins = append(corePlugins, + NewCommander(commander, loadedConfig), + ) + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureFileWatcher) { + corePlugins = append(corePlugins, + NewFileWatcher(loadedConfig, env), + NewFileWatchThrottle(), + ) + } + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsSender) && reporter != nil { + corePlugins = append(corePlugins, + NewMetricsSender(reporter), + ) + } + + corePlugins = append(corePlugins, + NewConfigReader(loadedConfig), + NewNginx(commander, binary, env, loadedConfig), + NewExtensions(loadedConfig, env), + NewFeatures(commander, loadedConfig, env, binary, loadedConfig.Version), + ) + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureRegistration) { + corePlugins = append(corePlugins, NewOneTimeRegistration(loadedConfig, binary, env, sdkGRPC.NewMessageMeta(uuid.NewString()))) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsCollection) || + (len(loadedConfig.Nginx.NginxCountingSocket) > 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxCounting)) { + corePlugins = append(corePlugins, NewMetrics(loadedConfig, env, binary)) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsThrottle) { + corePlugins = append(corePlugins, NewMetricsThrottle(loadedConfig, env)) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureDataPlaneStatus) { + corePlugins = append(corePlugins, NewDataPlaneStatus(loadedConfig, sdkGRPC.NewMessageMeta(uuid.NewString()), binary, env)) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureProcessWatcher) { + corePlugins = append(corePlugins, NewProcessWatcher(env, binary)) + } + + if loadedConfig.IsFeatureEnabled(agent_config.FeatureActivityEvents) { + corePlugins = append(corePlugins, NewEvents(loadedConfig, env, sdkGRPC.NewMessageMeta(uuid.NewString()), binary)) + } + + if loadedConfig.AgentAPI.Port != 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureAgentAPI) { + corePlugins = append(corePlugins, NewAgentAPI(loadedConfig, env, binary)) + } else { + log.Info("Agent API not configured") + } + + if len(loadedConfig.Nginx.NginxCountingSocket) > 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxCounting) { + corePlugins = append(corePlugins, NewNginxCounter(loadedConfig, binary, env)) + } + + if loadedConfig.Extensions != nil && len(loadedConfig.Extensions) > 0 { + for _, extension := range loadedConfig.Extensions { + switch { + case extension == agent_config.AdvancedMetricsExtensionPlugin: + advancedMetricsExtensionPlugin := extensions.NewAdvancedMetrics(env, loadedConfig, config.Viper.Get(agent_config.AdvancedMetricsExtensionPluginConfigKey)) + extensionPlugins = append(extensionPlugins, advancedMetricsExtensionPlugin) + case extension == agent_config.NginxAppProtectExtensionPlugin: + nginxAppProtectExtensionPlugin, err := extensions.NewNginxAppProtect(loadedConfig, env, config.Viper.Get(agent_config.NginxAppProtectExtensionPluginConfigKey)) + if err != nil { + log.Errorf("Unable to load the Nginx App Protect plugin due to the following error: %v", err) + } else { + extensionPlugins = append(extensionPlugins, nginxAppProtectExtensionPlugin) + } + case extension == agent_config.NginxAppProtectMonitoringExtensionPlugin: + nginxAppProtectMonitoringExtensionPlugin, err := extensions.NewNAPMonitoring(env, loadedConfig, config.Viper.Get(agent_config.NginxAppProtectMonitoringExtensionPluginConfigKey)) + if err != nil { + log.Errorf("Unable to load the Nginx App Protect Monitoring plugin due to the following error: %v", err) + } else { + extensionPlugins = append(extensionPlugins, nginxAppProtectMonitoringExtensionPlugin) + } + default: + log.Warnf("unknown extension configured: %s", extension) + } + } + } + + return corePlugins, extensionPlugins +} diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/dataplane_status.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/dataplane_status.go index 2160e50e7..d1aef6ae7 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/dataplane_status.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/dataplane_status.go @@ -48,7 +48,7 @@ const ( defaultMinInterval = time.Second * 30 ) -func NewDataPlaneStatus(config *config.Config, meta *proto.Metadata, binary core.NginxBinary, env core.Environment, version string) *DataPlaneStatus { +func NewDataPlaneStatus(config *config.Config, meta *proto.Metadata, binary core.NginxBinary, env core.Environment) *DataPlaneStatus { log.Tracef("Dataplane status interval %s", config.Dataplane.Status.PollInterval) pollInt := config.Dataplane.Status.PollInterval if pollInt < defaultMinInterval { @@ -62,7 +62,7 @@ func NewDataPlaneStatus(config *config.Config, meta *proto.Metadata, binary core meta: meta, binary: binary, env: env, - version: version, + version: config.Version, tags: &config.Tags, configDirs: config.ConfigDirs, reportInterval: config.Dataplane.Status.ReportInterval, diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/features.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/features.go index 7a17686a3..51f1867a2 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/features.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/features.go @@ -210,7 +210,7 @@ func (f *Features) enableRegistrationFeature(data string) []core.Plugin { } f.conf = conf - registration := NewOneTimeRegistration(f.conf, f.binary, f.env, sdkGRPC.NewMessageMeta(uuid.NewString()), f.version) + registration := NewOneTimeRegistration(f.conf, f.binary, f.env, sdkGRPC.NewMessageMeta(uuid.NewString())) return []core.Plugin{registration} } @@ -225,7 +225,7 @@ func (f *Features) enableDataPlaneStatusFeature(data string) []core.Plugin { } f.conf = conf - dataPlaneStatus := NewDataPlaneStatus(f.conf, sdkGRPC.NewMessageMeta(uuid.NewString()), f.binary, f.env, f.version) + dataPlaneStatus := NewDataPlaneStatus(f.conf, sdkGRPC.NewMessageMeta(uuid.NewString()), f.binary, f.env) return []core.Plugin{dataPlaneStatus} } diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go index 8d94b736d..c57209fc0 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go @@ -49,13 +49,12 @@ func NewOneTimeRegistration( binary core.NginxBinary, env core.Environment, meta *proto.Metadata, - version string, ) *OneTimeRegistration { // this might be slow so do on startup - host := env.NewHostInfo(version, &config.Tags, config.ConfigDirs, true) + host := env.NewHostInfo(config.Version, &config.Tags, config.ConfigDirs, true) return &OneTimeRegistration{ tags: &config.Tags, - agentVersion: version, + agentVersion: config.Version, meta: meta, config: config, env: env, diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 983b268cf..a2a9b10e4 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(aem.message, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", aem.message, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", From a33c4fd5b9ab8451fbb7f12bf0f0a1d46e9ef9a3 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Mon, 4 Sep 2023 16:01:25 +0100 Subject: [PATCH 06/20] local changes --- main.go | 1 - sdk/agent/events/meta_test.go | 4 ++-- src/core/grpc_test.go | 4 ++-- src/plugins/common_test.go | 10 +++++----- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index 001492e4e..a52c0f4e4 100644 --- a/main.go +++ b/main.go @@ -21,7 +21,6 @@ import ( "github.com/nginx/agent/v2/src/core/logger" "github.com/nginx/agent/v2/src/plugins" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) diff --git a/sdk/agent/events/meta_test.go b/sdk/agent/events/meta_test.go index a9e91308a..a8f055e65 100644 --- a/sdk/agent/events/meta_test.go +++ b/sdk/agent/events/meta_test.go @@ -47,7 +47,7 @@ func TestGenerateAgentStopEventCommand(t *testing.T) { []string{"tag3", "tag4"}, ) - expectedActivityEvent:= &eventsProto.ActivityEvent{ + expectedActivityEvent := &eventsProto.ActivityEvent{ Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", "agent-module", "v2.0", "54321", "test-host"), Dimensions: []*commonProto.Dimension{ { @@ -90,6 +90,6 @@ func TestGenerateAgentStopEventCommand(t *testing.T) { assert.NotNil(t, cmd.Meta) assert.Equal(t, proto.Command_NORMAL, cmd.Type) assert.NotNil(t, cmd.GetData()) - + assert.Equal(t, expected.GetEvents()[0].GetData(), cmd.GetData().(*proto.Command_EventReport).EventReport.GetEvents()[0].GetData()) } diff --git a/src/core/grpc_test.go b/src/core/grpc_test.go index 5663a6c01..b52ab51e5 100644 --- a/src/core/grpc_test.go +++ b/src/core/grpc_test.go @@ -16,7 +16,7 @@ func TestCreateGrpcClients(t *testing.T) { }, Server: config.Server{ GrpcPort: 6789, - Host: "192.0.2.4", + Host: "192.0.2.4", }, } @@ -38,7 +38,7 @@ func TestSetDialOptions(t *testing.T) { }, Server: config.Server{ GrpcPort: 67890, - Host: "192.0.2.5", + Host: "192.0.2.5", }, } diff --git a/src/plugins/common_test.go b/src/plugins/common_test.go index 0e1ce2b69..327130316 100644 --- a/src/plugins/common_test.go +++ b/src/plugins/common_test.go @@ -9,16 +9,16 @@ import ( ) func TestLoadPlugins(t *testing.T) { - // Create mock objects or use testing stubs for dependencies like 'commander', 'binary', 'env', 'reporter', 'loadedConfig', etc. + // Create mock objects or use testing stubs for dependencies like 'commander', 'binary', 'env', 'reporter', 'loadedConfig', etc. binary := tutils.NewMockNginxBinary() env := tutils.GetMockEnvWithProcess() cmdr := tutils.NewMockCommandClient() reporter := tutils.NewMockMetricsReportClient() - loadedConfig := &config.Config{ /* Set loadedConfig fields accordingly */ } - + loadedConfig := &config.Config{ /* Set loadedConfig fields accordingly */ } + corePlugins, extensionPlugins := LoadPlugins(cmdr, binary, env, reporter, loadedConfig) - - assert.NotNil(t, corePlugins) + + assert.NotNil(t, corePlugins) assert.Len(t, corePlugins, 5) assert.Len(t, extensionPlugins, 0) } From 040a456882d0d93328d7689254589d545aae6ff0 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Mon, 4 Sep 2023 16:40:11 +0100 Subject: [PATCH 07/20] move code around, combined with benchmark for moved code --- src/plugins/common_test.go | 57 +++++++++++++++++++++---- test/performance/metrics_test.go | 4 +- test/performance/plugins_test.go | 72 +++++++++++++++++++++++++++++--- 3 files changed, 117 insertions(+), 16 deletions(-) diff --git a/src/plugins/common_test.go b/src/plugins/common_test.go index 327130316..a37eb9bcb 100644 --- a/src/plugins/common_test.go +++ b/src/plugins/common_test.go @@ -3,22 +3,63 @@ package plugins import ( "testing" + sdk "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/v2/src/core/config" tutils "github.com/nginx/agent/v2/test/utils" "github.com/stretchr/testify/assert" ) func TestLoadPlugins(t *testing.T) { - // Create mock objects or use testing stubs for dependencies like 'commander', 'binary', 'env', 'reporter', 'loadedConfig', etc. - binary := tutils.NewMockNginxBinary() - env := tutils.GetMockEnvWithProcess() + binary := tutils.GetMockNginxBinary() + env := tutils.GetMockEnvWithHostAndProcess() cmdr := tutils.NewMockCommandClient() reporter := tutils.NewMockMetricsReportClient() - loadedConfig := &config.Config{ /* Set loadedConfig fields accordingly */ } - corePlugins, extensionPlugins := LoadPlugins(cmdr, binary, env, reporter, loadedConfig) + tests := []struct { + name string + loadedConfig *config.Config + expectedPluginSize int + expectedExtensionSize int + }{ + { + name: "default plugins", + loadedConfig: &config.Config{}, + expectedPluginSize: 5, + expectedExtensionSize: 0, + }, + { + name: "no plugins or extensions", + loadedConfig: &config.Config{ + Features: []string{}, + Extensions: []string{}, + }, + expectedPluginSize: 5, + expectedExtensionSize: 0, + }, + { + name: "all plugins and extensions", + loadedConfig: &config.Config{ + Features: sdk.GetDefaultFeatures(), + Extensions: sdk.GetKnownExtensions(), + AgentMetrics: config.AgentMetrics{ + BulkSize: 1, + ReportInterval: 1, + CollectionInterval: 1, + Mode: "aggregated", + }, + }, + expectedPluginSize: 14, + expectedExtensionSize: len(sdk.GetKnownExtensions()), + }, + } - assert.NotNil(t, corePlugins) - assert.Len(t, corePlugins, 5) - assert.Len(t, extensionPlugins, 0) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + corePlugins, extensionPlugins := LoadPlugins(cmdr, binary, env, reporter, tt.loadedConfig) + + assert.NotNil(t, corePlugins) + assert.Len(t, corePlugins, tt.expectedPluginSize) + assert.Len(t, extensionPlugins, tt.expectedExtensionSize) + }) + } } diff --git a/test/performance/metrics_test.go b/test/performance/metrics_test.go index 786f40a09..a3c1966b2 100644 --- a/test/performance/metrics_test.go +++ b/test/performance/metrics_test.go @@ -323,10 +323,10 @@ func startNginxAgent(b *testing.B) { plugins.NewNginx(commander, binary, env, &config.Config{}), plugins.NewCommander(commander, loadedConfig), plugins.NewMetricsSender(reporter), - plugins.NewOneTimeRegistration(loadedConfig, binary, env, sdkGRPC.NewMessageMeta(uuid.New().String()), "1.0.0"), + plugins.NewOneTimeRegistration(loadedConfig, binary, env, sdkGRPC.NewMessageMeta(uuid.New().String())), plugins.NewMetrics(loadedConfig, env, binary), plugins.NewMetricsThrottle(loadedConfig, env), - plugins.NewDataPlaneStatus(loadedConfig, sdkGRPC.NewMessageMeta(uuid.New().String()), binary, env, "1.0.0"), + plugins.NewDataPlaneStatus(loadedConfig, sdkGRPC.NewMessageMeta(uuid.New().String()), binary, env), } messagePipe := core.NewMessagePipe(ctx) diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index 408c43ab0..5cdd4fca3 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -5,11 +5,12 @@ import ( "testing" "time" + sdk "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" "github.com/nginx/agent/v2/src/plugins" - "github.com/nginx/agent/v2/test/utils" + tutils "github.com/nginx/agent/v2/test/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -68,13 +69,73 @@ func BenchmarkPlugin(b *testing.B) { plugin.AssertExpectations(b) } +func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { + binary := tutils.GetMockNginxBinary() + env := tutils.GetMockEnvWithHostAndProcess() + cmdr := tutils.NewMockCommandClient() + reporter := tutils.NewMockMetricsReportClient() + + tests := []struct { + name string + loadedConfig *config.Config + expectedPluginSize int + expectedExtensionSize int + }{ + { + name: "default plugins", + loadedConfig: &config.Config{}, + expectedPluginSize: 5, + expectedExtensionSize: 0, + }, + { + name: "no plugins or extensions", + loadedConfig: &config.Config{ + Features: []string{}, + Extensions: []string{}, + }, + expectedPluginSize: 5, + expectedExtensionSize: 0, + }, + { + name: "all plugins and extensions", + loadedConfig: &config.Config{ + Features: sdk.GetDefaultFeatures(), + Extensions: sdk.GetKnownExtensions(), + AgentMetrics: config.AgentMetrics{ + BulkSize: 1, + ReportInterval: 1, + CollectionInterval: 1, + Mode: "aggregated", + }, + }, + expectedPluginSize: 14, + expectedExtensionSize: len(sdk.GetKnownExtensions()), + }, + } + + for _, tt := range tests { + b.Run(tt.name, func(t *testing.B) { + for i := 0; i < b.N; i++ { + corePlugins, extensionPlugins := plugins.LoadPlugins(cmdr, binary, env, reporter, tt.loadedConfig) + + assert.NotNil(t, corePlugins) + assert.Len(t, corePlugins, tt.expectedPluginSize) + assert.Len(t, extensionPlugins, tt.expectedExtensionSize) + } + }) + } +} + func BenchmarkPluginOneTimeRegistration(b *testing.B) { var pluginsUnderTest []core.Plugin ctx, cancel := context.WithCancel(context.Background()) pipelineDone := make(chan bool) - config := config.Config{Nginx: config.Nginx{Debug: true}} + config := config.Config{ + Nginx: config.Nginx{Debug: true}, + Version: "1234", + } processID := "12345" detailsMap := map[string]*proto.NginxDetails{ @@ -84,13 +145,13 @@ func BenchmarkPluginOneTimeRegistration(b *testing.B) { }, } - binary := utils.NewMockNginxBinary() + binary := tutils.NewMockNginxBinary() binary.On("GetNginxDetailsMapFromProcesses", mock.Anything).Return(detailsMap) binary.On("GetNginxIDForProcess", mock.Anything).Return(processID) binary.On("GetNginxDetailsFromProcess", mock.Anything).Return(detailsMap[processID]) binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) - env := utils.NewMockEnvironment() + env := tutils.NewMockEnvironment() env.Mock.On("NewHostInfo", mock.Anything, mock.Anything, mock.Anything).Return(&proto.HostInfo{ Hostname: "test-host", }) @@ -102,11 +163,10 @@ func BenchmarkPluginOneTimeRegistration(b *testing.B) { }) meta := proto.Metadata{} - version := "1234" messagePipe := core.NewMessagePipe(ctx) for n := 0; n < b.N; n++ { - pluginsUnderTest = append(pluginsUnderTest, plugins.NewOneTimeRegistration(&config, binary, env, &meta, version)) + pluginsUnderTest = append(pluginsUnderTest, plugins.NewOneTimeRegistration(&config, binary, env, &meta)) } err := messagePipe.Register(b.N, pluginsUnderTest, []core.ExtensionPlugin{}) From 86a601f9d254ebc73ef054575e47a241d7ba2a34 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Mon, 4 Sep 2023 16:59:21 +0100 Subject: [PATCH 08/20] ommit the monitoring extension for now --- src/plugins/common_test.go | 10 ++++++---- test/performance/plugins_test.go | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/plugins/common_test.go b/src/plugins/common_test.go index a37eb9bcb..73bc9375e 100644 --- a/src/plugins/common_test.go +++ b/src/plugins/common_test.go @@ -39,8 +39,9 @@ func TestLoadPlugins(t *testing.T) { { name: "all plugins and extensions", loadedConfig: &config.Config{ - Features: sdk.GetDefaultFeatures(), - Extensions: sdk.GetKnownExtensions(), + Features: sdk.GetDefaultFeatures(), + // temporarily to figure out what's going on with the monitoring extension + Extensions: sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1], AgentMetrics: config.AgentMetrics{ BulkSize: 1, ReportInterval: 1, @@ -48,8 +49,9 @@ func TestLoadPlugins(t *testing.T) { Mode: "aggregated", }, }, - expectedPluginSize: 14, - expectedExtensionSize: len(sdk.GetKnownExtensions()), + expectedPluginSize: 14, + // temporarily to figure out what's going on with the monitoring extension + expectedExtensionSize: len(sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1]), }, } diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index 5cdd4fca3..8579aae71 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -99,8 +99,9 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { { name: "all plugins and extensions", loadedConfig: &config.Config{ - Features: sdk.GetDefaultFeatures(), - Extensions: sdk.GetKnownExtensions(), + Features: sdk.GetDefaultFeatures(), + // temporarily to figure out what's going on with the monitoring extension + Extensions: sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1], AgentMetrics: config.AgentMetrics{ BulkSize: 1, ReportInterval: 1, @@ -108,8 +109,9 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { Mode: "aggregated", }, }, - expectedPluginSize: 14, - expectedExtensionSize: len(sdk.GetKnownExtensions()), + expectedPluginSize: 14, + // temporarily to figure out what's going on with the monitoring extension + expectedExtensionSize: len(sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1]), }, } From 92d87eaaae3d5af50d175b63508aeac6ad2ac5c8 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Mon, 4 Sep 2023 18:45:11 +0100 Subject: [PATCH 09/20] Made BenchmarkFeaturesExtensionsAndPlugins benchmark a wider range, however seems flaky. Will try to amend --- .../nginx/agent/v2/test/utils/agent_config.go | 4 ++ .../nginx/agent/v2/test/utils/nginx.go | 4 +- test/performance/plugins_test.go | 64 +++++++++++++++++-- .../nginx/agent/v2/test/utils/agent_config.go | 4 ++ .../nginx/agent/v2/test/utils/nginx.go | 4 +- test/utils/agent_config.go | 4 ++ test/utils/nginx.go | 4 +- 7 files changed, 78 insertions(+), 10 deletions(-) diff --git a/test/integration/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go b/test/integration/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go index 58fa133dd..a9bae0bb6 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go @@ -46,6 +46,10 @@ func GetMockAgentConfig() *config.Config { CollectionInterval: 1, Mode: "aggregated", }, + Server: config.Server{ + Host: "127.0.0.1", + GrpcPort: 67890, + }, } } diff --git a/test/integration/vendor/github.com/nginx/agent/v2/test/utils/nginx.go b/test/integration/vendor/github.com/nginx/agent/v2/test/utils/nginx.go index 6980a98a7..53b2a9779 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/test/utils/nginx.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/test/utils/nginx.go @@ -124,8 +124,8 @@ func (m *MockNginxBinary) UpdateNginxDetailsFromProcesses(nginxProcesses []*core } func (m *MockNginxBinary) GetNginxIDForProcess(nginxProcess *core.Process) string { - args := m.Called(nginxProcess) - return args.String(0) + m.Called(nginxProcess) + return nginxProcess.Name } func (m *MockNginxBinary) GetNginxDetailsFromProcess(nginxProcess *core.Process) *proto.NginxDetails { diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index 8579aae71..3f6493397 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -6,6 +6,7 @@ import ( "time" sdk "github.com/nginx/agent/sdk/v2/agent/config" + "github.com/nginx/agent/sdk/v2/agent/events" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" @@ -70,35 +71,66 @@ func BenchmarkPlugin(b *testing.B) { } func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { + processID := "12345" + detailsMap := map[string]*proto.NginxDetails{ + processID: { + ProcessPath: "/path/to/nginx", + NginxId: processID, + }, + } + + procMap := map[string][]*proto.NginxDetails{ + processID: { + { + ProcessId: processID, + }, + }, + } + binary := tutils.GetMockNginxBinary() + binary.On("GetNginxDetailsMapFromProcesses", mock.Anything).Return(detailsMap) + binary.On("GetNginxIDForProcess", mock.Anything).Return(processID) + binary.On("UpdateNginxDetailsFromProcesses", mock.Anything).Return() + binary.On("GetChildProcesses").Return(procMap) + binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) + env := tutils.GetMockEnvWithHostAndProcess() - cmdr := tutils.NewMockCommandClient() - reporter := tutils.NewMockMetricsReportClient() + env.Mock.On("IsContainer").Return(false) + env.Mock.On("DiskDevices").Return([]string{"disk1", "disk2"}, nil) tests := []struct { name string loadedConfig *config.Config expectedPluginSize int expectedExtensionSize int + context context.Context }{ { - name: "default plugins", - loadedConfig: &config.Config{}, + name: "default plugins", + loadedConfig: &config.Config{ + Server: tutils.GetMockAgentConfig().Server, + }, expectedPluginSize: 5, expectedExtensionSize: 0, + context: context.Background(), }, { name: "no plugins or extensions", loadedConfig: &config.Config{ + Version: "v9.99.99999", + Server: tutils.GetMockAgentConfig().Server, Features: []string{}, Extensions: []string{}, }, expectedPluginSize: 5, expectedExtensionSize: 0, + context: context.Background(), }, { name: "all plugins and extensions", loadedConfig: &config.Config{ + Version: "v9.99.999", + Server: tutils.GetMockAgentConfig().Server, Features: sdk.GetDefaultFeatures(), // temporarily to figure out what's going on with the monitoring extension Extensions: sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1], @@ -112,17 +144,41 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { expectedPluginSize: 14, // temporarily to figure out what's going on with the monitoring extension expectedExtensionSize: len(sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1]), + context: context.Background(), }, } for _, tt := range tests { b.Run(tt.name, func(t *testing.B) { for i := 0; i < b.N; i++ { + b.ResetTimer() + ctx, cancel := context.WithCancel(tt.context) + + controller, cmdr, reporter := core.CreateGrpcClients(ctx, tt.loadedConfig) corePlugins, extensionPlugins := plugins.LoadPlugins(cmdr, binary, env, reporter, tt.loadedConfig) + pipe := core.InitializePipe(ctx, corePlugins, extensionPlugins, 20) + + event := events.NewAgentEventMeta(config.MODULE, + tt.loadedConfig.Version, + "1234", + "Initialize Agent", + env.GetHostname(), + env.GetSystemUUID(), + tt.loadedConfig.InstanceGroup, + tt.loadedConfig.Tags) + + pipe.Process(core.NewMessage(core.AgentStarted, event)) + core.HandleSignals(ctx, cmdr, tt.loadedConfig, env, pipe, cancel, controller) + + go func() { + pipe.Run() + }() + assert.NotNil(t, corePlugins) assert.Len(t, corePlugins, tt.expectedPluginSize) assert.Len(t, extensionPlugins, tt.expectedExtensionSize) + cancel() } }) } diff --git a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go index 58fa133dd..a9bae0bb6 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go @@ -46,6 +46,10 @@ func GetMockAgentConfig() *config.Config { CollectionInterval: 1, Mode: "aggregated", }, + Server: config.Server{ + Host: "127.0.0.1", + GrpcPort: 67890, + }, } } diff --git a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/nginx.go b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/nginx.go index 6980a98a7..53b2a9779 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/nginx.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/nginx.go @@ -124,8 +124,8 @@ func (m *MockNginxBinary) UpdateNginxDetailsFromProcesses(nginxProcesses []*core } func (m *MockNginxBinary) GetNginxIDForProcess(nginxProcess *core.Process) string { - args := m.Called(nginxProcess) - return args.String(0) + m.Called(nginxProcess) + return nginxProcess.Name } func (m *MockNginxBinary) GetNginxDetailsFromProcess(nginxProcess *core.Process) *proto.NginxDetails { diff --git a/test/utils/agent_config.go b/test/utils/agent_config.go index 58fa133dd..a9bae0bb6 100644 --- a/test/utils/agent_config.go +++ b/test/utils/agent_config.go @@ -46,6 +46,10 @@ func GetMockAgentConfig() *config.Config { CollectionInterval: 1, Mode: "aggregated", }, + Server: config.Server{ + Host: "127.0.0.1", + GrpcPort: 67890, + }, } } diff --git a/test/utils/nginx.go b/test/utils/nginx.go index 6980a98a7..53b2a9779 100644 --- a/test/utils/nginx.go +++ b/test/utils/nginx.go @@ -124,8 +124,8 @@ func (m *MockNginxBinary) UpdateNginxDetailsFromProcesses(nginxProcesses []*core } func (m *MockNginxBinary) GetNginxIDForProcess(nginxProcess *core.Process) string { - args := m.Called(nginxProcess) - return args.String(0) + m.Called(nginxProcess) + return nginxProcess.Name } func (m *MockNginxBinary) GetNginxDetailsFromProcess(nginxProcess *core.Process) *proto.NginxDetails { From b9aca4c3bbe05ec50b3b108b5ef4d399b8f84ea9 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Tue, 5 Sep 2023 12:21:02 +0100 Subject: [PATCH 10/20] updated tests and code --- sdk/client/controller.go | 7 +- src/core/metrics/sources/nginx_worker_test.go | 14 +-- src/plugins/metrics_test.go | 8 +- .../nginx/agent/sdk/v2/client/controller.go | 7 +- .../nginx/agent/v2/test/utils/process.go | 12 +++ test/performance/plugins_test.go | 96 ++++++++----------- .../nginx/agent/sdk/v2/client/controller.go | 7 +- .../nginx/agent/v2/test/utils/process.go | 12 +++ test/utils/process.go | 12 +++ .../nginx/agent/sdk/v2/client/controller.go | 7 +- 10 files changed, 99 insertions(+), 83 deletions(-) diff --git a/sdk/client/controller.go b/sdk/client/controller.go index b89efd01b..7fbf57e16 100644 --- a/sdk/client/controller.go +++ b/sdk/client/controller.go @@ -18,6 +18,7 @@ func NewClientController() Controller { type ctrl struct { ctx context.Context + cncl context.CancelFunc clients []Client } @@ -28,8 +29,7 @@ func (c *ctrl) WithClient(client Client) Controller { } func (c *ctrl) WithContext(ctx context.Context) Controller { - c.ctx = ctx - + c.ctx, c.cncl = context.WithCancel(ctx) return c } @@ -49,6 +49,7 @@ func (c *ctrl) Connect() error { } func (c *ctrl) Close() error { + defer c.cncl() var retErr error for _, client := range c.clients { if err := client.Close(); err != nil { @@ -65,4 +66,4 @@ func (c *ctrl) Close() error { func (c *ctrl) Context() context.Context { return c.ctx -} +} \ No newline at end of file diff --git a/src/core/metrics/sources/nginx_worker_test.go b/src/core/metrics/sources/nginx_worker_test.go index 119377df2..fda857e0a 100644 --- a/src/core/metrics/sources/nginx_worker_test.go +++ b/src/core/metrics/sources/nginx_worker_test.go @@ -16,7 +16,7 @@ import ( "github.com/google/uuid" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/v2/src/core/metrics" - "github.com/nginx/agent/v2/test/utils" + tutils "github.com/nginx/agent/v2/test/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -27,13 +27,7 @@ var ( instanceGroup = "my_instances" nginxId = uuid.New().String() systemId = uuid.New().String() - procMap = map[string][]*proto.NginxDetails{ - "1": { - { - ProcessId: "1", - }, - }, - } + procMap = tutils.GetProcessMap() ) type MockWorkerClient struct { @@ -58,14 +52,14 @@ func TestNginxWorkerCollector(t *testing.T) { NginxId: nginxId, } - mockBinary := &utils.MockNginxBinary{} + mockBinary := &tutils.MockNginxBinary{} mockClient := &MockWorkerClient{} n := NewNginxWorker(dimensions, OSSNamespace, mockBinary, mockClient) mockBinary.On("GetChildProcesses").Return(procMap) - mockClient.On("GetWorkerStats", procMap["1"]).Return(&WorkerStats{ + mockClient.On("GetWorkerStats", procMap["12345"]).Return(&WorkerStats{ Workers: &Workers{ Count: 1.00, KbsR: 1.00, diff --git a/src/plugins/metrics_test.go b/src/plugins/metrics_test.go index 64c943933..a3932c372 100644 --- a/src/plugins/metrics_test.go +++ b/src/plugins/metrics_test.go @@ -155,13 +155,7 @@ func TestMetricsProcessNginxDetailProcUpdate(t *testing.T) { }, }).Once() env.On("IsContainer").Return(false) - env.On("GetChildProcesses").Return(map[string][]*proto.NginxDetails{ - "1": { - { - ProcessId: "1", - }, - }, - }) + env.On("GetChildProcesses").Return(tutils.GetProcessMap()) metricsPlugin := NewMetrics(config, env, binary) metricsPlugin.collectors = []metrics.Collector{ diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/client/controller.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/client/controller.go index b89efd01b..7fbf57e16 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/client/controller.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/client/controller.go @@ -18,6 +18,7 @@ func NewClientController() Controller { type ctrl struct { ctx context.Context + cncl context.CancelFunc clients []Client } @@ -28,8 +29,7 @@ func (c *ctrl) WithClient(client Client) Controller { } func (c *ctrl) WithContext(ctx context.Context) Controller { - c.ctx = ctx - + c.ctx, c.cncl = context.WithCancel(ctx) return c } @@ -49,6 +49,7 @@ func (c *ctrl) Connect() error { } func (c *ctrl) Close() error { + defer c.cncl() var retErr error for _, client := range c.clients { if err := client.Close(); err != nil { @@ -65,4 +66,4 @@ func (c *ctrl) Close() error { func (c *ctrl) Context() context.Context { return c.ctx -} +} \ No newline at end of file diff --git a/test/integration/vendor/github.com/nginx/agent/v2/test/utils/process.go b/test/integration/vendor/github.com/nginx/agent/v2/test/utils/process.go index dfd405618..d067e0ef6 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/test/utils/process.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/test/utils/process.go @@ -5,6 +5,8 @@ import ( "os" "os/exec" "time" + + "github.com/nginx/agent/sdk/v2/proto" ) // StartFakeProcesses creates a fake process for each of the string names and @@ -29,3 +31,13 @@ func StartFakeProcesses(names []string, fakeProcsDuration string) func() { } } } + +func GetProcessMap() map[string][]*proto.NginxDetails { + return map[string][]*proto.NginxDetails{ + "12345": { + { + ProcessId: "1", + }, + }, + } +} \ No newline at end of file diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index 3f6493397..821a8a067 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -71,25 +71,12 @@ func BenchmarkPlugin(b *testing.B) { } func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { - processID := "12345" - detailsMap := map[string]*proto.NginxDetails{ - processID: { - ProcessPath: "/path/to/nginx", - NginxId: processID, - }, - } - - procMap := map[string][]*proto.NginxDetails{ - processID: { - { - ProcessId: processID, - }, - }, - } + detailsMap := tutils.GetDetailsMap() + procMap := tutils.GetProcessMap() binary := tutils.GetMockNginxBinary() binary.On("GetNginxDetailsMapFromProcesses", mock.Anything).Return(detailsMap) - binary.On("GetNginxIDForProcess", mock.Anything).Return(processID) + binary.On("GetNginxIDForProcess", mock.Anything).Return("12345") binary.On("UpdateNginxDetailsFromProcesses", mock.Anything).Return() binary.On("GetChildProcesses").Return(procMap) binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) @@ -97,35 +84,33 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { env := tutils.GetMockEnvWithHostAndProcess() env.Mock.On("IsContainer").Return(false) env.Mock.On("DiskDevices").Return([]string{"disk1", "disk2"}, nil) + env.Mock.On("GetNetOverflow").Return(0.0, nil) tests := []struct { name string loadedConfig *config.Config expectedPluginSize int expectedExtensionSize int - context context.Context }{ - { - name: "default plugins", - loadedConfig: &config.Config{ - Server: tutils.GetMockAgentConfig().Server, - }, - expectedPluginSize: 5, - expectedExtensionSize: 0, - context: context.Background(), - }, - { - name: "no plugins or extensions", - loadedConfig: &config.Config{ - Version: "v9.99.99999", - Server: tutils.GetMockAgentConfig().Server, - Features: []string{}, - Extensions: []string{}, - }, - expectedPluginSize: 5, - expectedExtensionSize: 0, - context: context.Background(), - }, + // { + // name: "default plugins", + // loadedConfig: &config.Config{ + // Server: tutils.GetMockAgentConfig().Server, + // }, + // expectedPluginSize: 5, + // expectedExtensionSize: 0, + // }, + // { + // name: "no plugins or extensions", + // loadedConfig: &config.Config{ + // Version: "v9.99.99999", + // Server: tutils.GetMockAgentConfig().Server, + // Features: []string{}, + // Extensions: []string{}, + // }, + // expectedPluginSize: 5, + // expectedExtensionSize: 0, + // }, { name: "all plugins and extensions", loadedConfig: &config.Config{ @@ -140,11 +125,18 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { CollectionInterval: 1, Mode: "aggregated", }, + AgentAPI: config.AgentAPI{ + Port: 2345, + Key: "", + Cert: "", + }, + Dataplane: config.Dataplane{ + Status: config.Status{PollInterval: 60 * time.Second}, + }, }, - expectedPluginSize: 14, + expectedPluginSize: 15, // temporarily to figure out what's going on with the monitoring extension expectedExtensionSize: len(sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1]), - context: context.Background(), }, } @@ -152,12 +144,14 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { b.Run(tt.name, func(t *testing.B) { for i := 0; i < b.N; i++ { b.ResetTimer() - ctx, cancel := context.WithCancel(tt.context) + ctx, cancel := context.WithCancel(context.Background()) + pipelineDone := make(chan bool) controller, cmdr, reporter := core.CreateGrpcClients(ctx, tt.loadedConfig) corePlugins, extensionPlugins := plugins.LoadPlugins(cmdr, binary, env, reporter, tt.loadedConfig) pipe := core.InitializePipe(ctx, corePlugins, extensionPlugins, 20) + core.HandleSignals(ctx, cmdr, tt.loadedConfig, env, pipe, cancel, controller) event := events.NewAgentEventMeta(config.MODULE, tt.loadedConfig.Version, @@ -169,16 +163,20 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { tt.loadedConfig.Tags) pipe.Process(core.NewMessage(core.AgentStarted, event)) - core.HandleSignals(ctx, cmdr, tt.loadedConfig, env, pipe, cancel, controller) go func() { pipe.Run() + pipelineDone <- true }() + <-pipelineDone + assert.NotNil(t, corePlugins) assert.Len(t, corePlugins, tt.expectedPluginSize) assert.Len(t, extensionPlugins, tt.expectedExtensionSize) - cancel() + + controller.Close() + ctx.Done() } }) } @@ -209,17 +207,7 @@ func BenchmarkPluginOneTimeRegistration(b *testing.B) { binary.On("GetNginxDetailsFromProcess", mock.Anything).Return(detailsMap[processID]) binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) - env := tutils.NewMockEnvironment() - env.Mock.On("NewHostInfo", mock.Anything, mock.Anything, mock.Anything).Return(&proto.HostInfo{ - Hostname: "test-host", - }) - env.Mock.On("Processes", mock.Anything).Return([]*core.Process{ - { - Name: processID, - IsMaster: true, - }, - }) - + env := tutils.GetMockEnvWithHostAndProcess() meta := proto.Metadata{} messagePipe := core.NewMessagePipe(ctx) diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/client/controller.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/client/controller.go index b89efd01b..7fbf57e16 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/client/controller.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/client/controller.go @@ -18,6 +18,7 @@ func NewClientController() Controller { type ctrl struct { ctx context.Context + cncl context.CancelFunc clients []Client } @@ -28,8 +29,7 @@ func (c *ctrl) WithClient(client Client) Controller { } func (c *ctrl) WithContext(ctx context.Context) Controller { - c.ctx = ctx - + c.ctx, c.cncl = context.WithCancel(ctx) return c } @@ -49,6 +49,7 @@ func (c *ctrl) Connect() error { } func (c *ctrl) Close() error { + defer c.cncl() var retErr error for _, client := range c.clients { if err := client.Close(); err != nil { @@ -65,4 +66,4 @@ func (c *ctrl) Close() error { func (c *ctrl) Context() context.Context { return c.ctx -} +} \ No newline at end of file diff --git a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/process.go b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/process.go index dfd405618..d067e0ef6 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/process.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/process.go @@ -5,6 +5,8 @@ import ( "os" "os/exec" "time" + + "github.com/nginx/agent/sdk/v2/proto" ) // StartFakeProcesses creates a fake process for each of the string names and @@ -29,3 +31,13 @@ func StartFakeProcesses(names []string, fakeProcsDuration string) func() { } } } + +func GetProcessMap() map[string][]*proto.NginxDetails { + return map[string][]*proto.NginxDetails{ + "12345": { + { + ProcessId: "1", + }, + }, + } +} \ No newline at end of file diff --git a/test/utils/process.go b/test/utils/process.go index dfd405618..d067e0ef6 100644 --- a/test/utils/process.go +++ b/test/utils/process.go @@ -5,6 +5,8 @@ import ( "os" "os/exec" "time" + + "github.com/nginx/agent/sdk/v2/proto" ) // StartFakeProcesses creates a fake process for each of the string names and @@ -29,3 +31,13 @@ func StartFakeProcesses(names []string, fakeProcsDuration string) func() { } } } + +func GetProcessMap() map[string][]*proto.NginxDetails { + return map[string][]*proto.NginxDetails{ + "12345": { + { + ProcessId: "1", + }, + }, + } +} \ No newline at end of file diff --git a/vendor/github.com/nginx/agent/sdk/v2/client/controller.go b/vendor/github.com/nginx/agent/sdk/v2/client/controller.go index b89efd01b..7fbf57e16 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/client/controller.go +++ b/vendor/github.com/nginx/agent/sdk/v2/client/controller.go @@ -18,6 +18,7 @@ func NewClientController() Controller { type ctrl struct { ctx context.Context + cncl context.CancelFunc clients []Client } @@ -28,8 +29,7 @@ func (c *ctrl) WithClient(client Client) Controller { } func (c *ctrl) WithContext(ctx context.Context) Controller { - c.ctx = ctx - + c.ctx, c.cncl = context.WithCancel(ctx) return c } @@ -49,6 +49,7 @@ func (c *ctrl) Connect() error { } func (c *ctrl) Close() error { + defer c.cncl() var retErr error for _, client := range c.clients { if err := client.Close(); err != nil { @@ -65,4 +66,4 @@ func (c *ctrl) Close() error { func (c *ctrl) Context() context.Context { return c.ctx -} +} \ No newline at end of file From d0670b26751ce53e557fe1c13e933c081cdca6bf Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Tue, 5 Sep 2023 12:21:40 +0100 Subject: [PATCH 11/20] format --- sdk/client/controller.go | 2 +- .../vendor/github.com/nginx/agent/sdk/v2/client/controller.go | 2 +- .../vendor/github.com/nginx/agent/v2/test/utils/process.go | 2 +- test/performance/plugins_test.go | 2 +- .../vendor/github.com/nginx/agent/sdk/v2/client/controller.go | 2 +- .../vendor/github.com/nginx/agent/v2/test/utils/process.go | 2 +- test/utils/process.go | 2 +- vendor/github.com/nginx/agent/sdk/v2/client/controller.go | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sdk/client/controller.go b/sdk/client/controller.go index 7fbf57e16..7117269d0 100644 --- a/sdk/client/controller.go +++ b/sdk/client/controller.go @@ -66,4 +66,4 @@ func (c *ctrl) Close() error { func (c *ctrl) Context() context.Context { return c.ctx -} \ No newline at end of file +} diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/client/controller.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/client/controller.go index 7fbf57e16..7117269d0 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/client/controller.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/client/controller.go @@ -66,4 +66,4 @@ func (c *ctrl) Close() error { func (c *ctrl) Context() context.Context { return c.ctx -} \ No newline at end of file +} diff --git a/test/integration/vendor/github.com/nginx/agent/v2/test/utils/process.go b/test/integration/vendor/github.com/nginx/agent/v2/test/utils/process.go index d067e0ef6..6c8c5f61f 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/test/utils/process.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/test/utils/process.go @@ -40,4 +40,4 @@ func GetProcessMap() map[string][]*proto.NginxDetails { }, }, } -} \ No newline at end of file +} diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index 821a8a067..7c8310c92 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -174,7 +174,7 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { assert.NotNil(t, corePlugins) assert.Len(t, corePlugins, tt.expectedPluginSize) assert.Len(t, extensionPlugins, tt.expectedExtensionSize) - + controller.Close() ctx.Done() } diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/client/controller.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/client/controller.go index 7fbf57e16..7117269d0 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/client/controller.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/client/controller.go @@ -66,4 +66,4 @@ func (c *ctrl) Close() error { func (c *ctrl) Context() context.Context { return c.ctx -} \ No newline at end of file +} diff --git a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/process.go b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/process.go index d067e0ef6..6c8c5f61f 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/process.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/process.go @@ -40,4 +40,4 @@ func GetProcessMap() map[string][]*proto.NginxDetails { }, }, } -} \ No newline at end of file +} diff --git a/test/utils/process.go b/test/utils/process.go index d067e0ef6..6c8c5f61f 100644 --- a/test/utils/process.go +++ b/test/utils/process.go @@ -40,4 +40,4 @@ func GetProcessMap() map[string][]*proto.NginxDetails { }, }, } -} \ No newline at end of file +} diff --git a/vendor/github.com/nginx/agent/sdk/v2/client/controller.go b/vendor/github.com/nginx/agent/sdk/v2/client/controller.go index 7fbf57e16..7117269d0 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/client/controller.go +++ b/vendor/github.com/nginx/agent/sdk/v2/client/controller.go @@ -66,4 +66,4 @@ func (c *ctrl) Close() error { func (c *ctrl) Context() context.Context { return c.ctx -} \ No newline at end of file +} From 6ff8b508cda6d94210c2b215c55c2dc2c86ad151 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Tue, 5 Sep 2023 15:07:05 +0100 Subject: [PATCH 12/20] fixed the test --- test/performance/plugins_test.go | 104 +++++++++++++++---------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index 7c8310c92..e04f7ac98 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -6,7 +6,6 @@ import ( "time" sdk "github.com/nginx/agent/sdk/v2/agent/config" - "github.com/nginx/agent/sdk/v2/agent/events" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" @@ -92,25 +91,46 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { expectedPluginSize int expectedExtensionSize int }{ - // { - // name: "default plugins", - // loadedConfig: &config.Config{ - // Server: tutils.GetMockAgentConfig().Server, - // }, - // expectedPluginSize: 5, - // expectedExtensionSize: 0, - // }, - // { - // name: "no plugins or extensions", - // loadedConfig: &config.Config{ - // Version: "v9.99.99999", - // Server: tutils.GetMockAgentConfig().Server, - // Features: []string{}, - // Extensions: []string{}, - // }, - // expectedPluginSize: 5, - // expectedExtensionSize: 0, - // }, + { + name: "default plugins and no extensions", + loadedConfig: &config.Config{ + Server: tutils.GetMockAgentConfig().Server, + AgentMetrics: config.AgentMetrics{ + BulkSize: 1, + ReportInterval: 1, + CollectionInterval: 1, + Mode: "aggregated", + }, + AgentAPI: config.AgentAPI{ + Port: 23456, + Key: "", + Cert: "", + }, + Dataplane: config.Dataplane{ + Status: config.Status{PollInterval: 30 * time.Second}, + }, + }, + expectedPluginSize: 5, + expectedExtensionSize: 0, + }, + { + name: "default plugins and all extensions", + loadedConfig: &config.Config{ + Extensions: sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1], + Server: tutils.GetMockAgentConfig().Server, + AgentMetrics: config.AgentMetrics{ + BulkSize: 1, + ReportInterval: 1, + CollectionInterval: 1, + Mode: "aggregated", + }, + Dataplane: config.Dataplane{ + Status: config.Status{PollInterval: 30 * time.Second}, + }, + }, + expectedPluginSize: 5, + expectedExtensionSize: 2, + }, { name: "all plugins and extensions", loadedConfig: &config.Config{ @@ -131,7 +151,7 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { Cert: "", }, Dataplane: config.Dataplane{ - Status: config.Status{PollInterval: 60 * time.Second}, + Status: config.Status{PollInterval: 30 * time.Second}, }, }, expectedPluginSize: 15, @@ -141,43 +161,23 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { } for _, tt := range tests { + ctx, cancel := context.WithCancel(context.Background()) + var pipe core.MessagePipeInterface + var corePlugins []core.Plugin + var extensionPlugins []core.ExtensionPlugin + b.Run(tt.name, func(t *testing.B) { for i := 0; i < b.N; i++ { b.ResetTimer() - ctx, cancel := context.WithCancel(context.Background()) - pipelineDone := make(chan bool) - controller, cmdr, reporter := core.CreateGrpcClients(ctx, tt.loadedConfig) - corePlugins, extensionPlugins := plugins.LoadPlugins(cmdr, binary, env, reporter, tt.loadedConfig) - - pipe := core.InitializePipe(ctx, corePlugins, extensionPlugins, 20) + corePlugins, extensionPlugins = plugins.LoadPlugins(cmdr, binary, env, reporter, tt.loadedConfig) + pipe = core.InitializePipe(ctx, corePlugins, extensionPlugins, 20) core.HandleSignals(ctx, cmdr, tt.loadedConfig, env, pipe, cancel, controller) - - event := events.NewAgentEventMeta(config.MODULE, - tt.loadedConfig.Version, - "1234", - "Initialize Agent", - env.GetHostname(), - env.GetSystemUUID(), - tt.loadedConfig.InstanceGroup, - tt.loadedConfig.Tags) - - pipe.Process(core.NewMessage(core.AgentStarted, event)) - - go func() { - pipe.Run() - pipelineDone <- true - }() - - <-pipelineDone - - assert.NotNil(t, corePlugins) - assert.Len(t, corePlugins, tt.expectedPluginSize) - assert.Len(t, extensionPlugins, tt.expectedExtensionSize) - - controller.Close() - ctx.Done() } + + assert.NotNil(t, corePlugins) + assert.Len(t, corePlugins, tt.expectedPluginSize) + assert.Len(t, extensionPlugins, tt.expectedExtensionSize) }) } } From 570a4534985a64c3d4edcc4810d95b3a9b94d12b Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Tue, 5 Sep 2023 15:09:07 +0100 Subject: [PATCH 13/20] formatting --- test/performance/plugins_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/performance/plugins_test.go b/test/performance/plugins_test.go index e04f7ac98..719928d39 100644 --- a/test/performance/plugins_test.go +++ b/test/performance/plugins_test.go @@ -117,7 +117,7 @@ func BenchmarkFeaturesExtensionsAndPlugins(b *testing.B) { name: "default plugins and all extensions", loadedConfig: &config.Config{ Extensions: sdk.GetKnownExtensions()[:len(sdk.GetKnownExtensions())-1], - Server: tutils.GetMockAgentConfig().Server, + Server: tutils.GetMockAgentConfig().Server, AgentMetrics: config.AgentMetrics{ BulkSize: 1, ReportInterval: 1, From 2c9f827fe4acc74084951fbccb8e466d9979c8c0 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Tue, 5 Sep 2023 15:29:59 +0100 Subject: [PATCH 14/20] fix test --- sdk/client/controller_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/client/controller_test.go b/sdk/client/controller_test.go index 2962331d9..4a445c044 100644 --- a/sdk/client/controller_test.go +++ b/sdk/client/controller_test.go @@ -22,7 +22,7 @@ func TestControllerContext(t *testing.T) { controller := NewClientController() controller.WithContext(ctx) - assert.Equal(t, ctx, controller.Context()) + assert.NotNil(t, controller.Context()) t.Cleanup(func() { controller.Close() From 2cc05c72651bec4174dac337efd2de0c287ca3b6 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Thu, 7 Sep 2023 15:32:02 +0100 Subject: [PATCH 15/20] tidying of code --- sdk/agent/events/meta.go | 114 ++++++++++++++++-- sdk/agent/events/meta_test.go | 65 +++++++++- sdk/agent/events/types.go | 4 + src/plugins/events.go | 89 ++------------ .../nginx/agent/sdk/v2/agent/events/meta.go | 114 ++++++++++++++++-- .../nginx/agent/sdk/v2/agent/events/types.go | 4 + .../nginx/agent/sdk/v2/agent/events/meta.go | 114 ++++++++++++++++-- .../nginx/agent/sdk/v2/agent/events/types.go | 4 + .../nginx/agent/v2/src/plugins/events.go | 89 ++------------ .../nginx/agent/sdk/v2/agent/events/meta.go | 114 ++++++++++++++++-- .../nginx/agent/sdk/v2/agent/events/types.go | 4 + 11 files changed, 528 insertions(+), 187 deletions(-) diff --git a/sdk/agent/events/meta.go b/sdk/agent/events/meta.go index a2a9b10e4..f85880faf 100644 --- a/sdk/agent/events/meta.go +++ b/sdk/agent/events/meta.go @@ -23,26 +23,26 @@ type AgentEventMeta struct { module string version string pid string - message string hostname string systemUuid string instanceGroup string - tags []string + tags string + tagsRaw []string } func NewAgentEventMeta( - module, version, pid, message, hostname, systemUuid, instanceGroup string, + module, version, pid, hostname, systemUuid, instanceGroup string, tags []string, ) *AgentEventMeta { return &AgentEventMeta{ module: module, version: version, pid: pid, - message: message, hostname: hostname, systemUuid: systemUuid, instanceGroup: instanceGroup, - tags: tags, + tagsRaw: tags, + tags: strings.Join(tags, ","), } } @@ -54,9 +54,58 @@ func (aem *AgentEventMeta) GetPid() string { return aem.pid } +func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { + activityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: aem.systemUuid, + }, + { + Name: "hostname", + Value: aem.hostname, + }, + { + Name: "instance_group", + Value: aem.instanceGroup, + }, + { + Name: "system.tags", + Value: aem.tags, + }, + }, + } + + event := &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: uuid.NewString(), + Module: aem.module, + Timestamp: types.TimestampNow(), + EventLevel: WARN_EVENT_LEVEL, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } + + return &proto.Command{ + Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), + Type: proto.Command_NORMAL, + Data: &proto.Command_EventReport{ + EventReport: &eventsProto.EventReport{ + Events: []*eventsProto.Event{event}, + }, + }, + } +} + func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", aem.message, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -72,7 +121,7 @@ func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { }, { Name: "system.tags", - Value: strings.Join(aem.tags, ","), + Value: aem.tags, }, }, } @@ -102,3 +151,54 @@ func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { }, } } + +func (aem *AgentEventMeta) CreateAgentEvent(timestamp *types.Timestamp, level, message, correlationId, module string) *eventsProto.Event { + activityEvent := aem.CreateActivityEvent(message, "") // blank nginxId, this relates to agent not it's nginx instances + + return &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: correlationId, + Module: module, + Timestamp: timestamp, + EventLevel: level, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } +} + +func (aem *AgentEventMeta) CreateActivityEvent(message string, nginxId string) *eventsProto.ActivityEvent { + activityEvent := &eventsProto.ActivityEvent{ + Message: message, + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: aem.systemUuid, + }, + { + Name: "hostname", + Value: aem.hostname, + }, + { + Name: "instance_group", + Value: aem.instanceGroup, + }, + { + Name: "system.tags", + Value: aem.tags, + }, + }, + } + + if nginxId != "" { + nginxDim := []*commonProto.Dimension{{Name: "nginx_id", Value: nginxId}} + activityEvent.Dimensions = append(nginxDim, activityEvent.Dimensions...) + } + + return activityEvent +} + diff --git a/sdk/agent/events/meta_test.go b/sdk/agent/events/meta_test.go index a8f055e65..6674e4db9 100644 --- a/sdk/agent/events/meta_test.go +++ b/sdk/agent/events/meta_test.go @@ -16,31 +16,86 @@ func TestNewAgentEventMeta(t *testing.T) { module := "nginx-agent" version := "v1.0" pid := "12345" - message := "Sample message: Version=%s, PID=%s, Hostname=%s" hostname := "example-host" systemUuid := "system-uuid" instanceGroup := "group1" tags := []string{"tag1", "tag2"} - meta := NewAgentEventMeta(module, version, pid, message, hostname, systemUuid, instanceGroup, tags) + meta := NewAgentEventMeta(module, version, pid, hostname, systemUuid, instanceGroup, tags) assert.NotNil(t, meta) assert.Equal(t, version, meta.version) assert.Equal(t, pid, meta.pid) - assert.Equal(t, message, meta.message) assert.Equal(t, hostname, meta.hostname) assert.Equal(t, systemUuid, meta.systemUuid) assert.Equal(t, instanceGroup, meta.instanceGroup) assert.Equal(t, tags, meta.tags) } -func TestGenerateAgentStopEventCommand(t *testing.T) { +func TestGenerateAgentStartEventCommand(t *testing.T) { agentEvent := NewAgentEventMeta( "agent-module", "v2.0", "54321", + "test-host", + "test-uuid", + "group2", + []string{"tag3", "tag4"}, + ) + + expectedActivityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf("%s %s started on %s with pid %s", "nginx-agent", "v2.0", "54321", "test-host"), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: "test-uuid", + }, + { + Name: "hostname", + Value: "test-host", + }, + { + Name: "instance_group", + Value: "group2", + }, + { + Name: "system.tags", + Value: strings.Join([]string{"tag3", "tag4"}, ","), + }, + }, + } + + expected := &eventsProto.EventReport{ + Events: []*eventsProto.Event{ + { + Metadata: &eventsProto.Metadata{ + Module: agentEvent.module, + Type: AGENT_EVENT_TYPE, + Category: CONFIG_CATEGORY, + EventLevel: ERROR_EVENT_LEVEL, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: expectedActivityEvent, + }, + }, + }, + } + + cmd := agentEvent.GenerateAgentStartEventCommand() + assert.NotNil(t, cmd) + assert.NotNil(t, cmd.Meta) + assert.Equal(t, proto.Command_NORMAL, cmd.Type) + assert.NotNil(t, cmd.GetData()) + + assert.Equal(t, expected.GetEvents()[0].GetData(), cmd.GetData().(*proto.Command_EventReport).EventReport.GetEvents()[0].GetData()) +} + +func TestGenerateAgentStopEventCommand(t *testing.T) { + agentEvent := NewAgentEventMeta( "agent-module", + "v2.0", + "54321", "test-host", "test-uuid", "group2", @@ -48,7 +103,7 @@ func TestGenerateAgentStopEventCommand(t *testing.T) { ) expectedActivityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", "agent-module", "v2.0", "54321", "test-host"), + Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", "nginx-agent", "v2.0", "54321", "test-host"), Dimensions: []*commonProto.Dimension{ { Name: "system_id", diff --git a/sdk/agent/events/types.go b/sdk/agent/events/types.go index 0340d130d..275abc2a0 100644 --- a/sdk/agent/events/types.go +++ b/sdk/agent/events/types.go @@ -16,4 +16,8 @@ const ( WARN_EVENT_LEVEL = "WARN" ERROR_EVENT_LEVEL = "ERROR" CRITICAL_EVENT_LEVEL = "CRITICAL" + + // Messages + AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" + AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" ) diff --git a/src/plugins/events.go b/src/plugins/events.go index 9c116982e..2c2fe2661 100644 --- a/src/plugins/events.go +++ b/src/plugins/events.go @@ -10,7 +10,6 @@ package plugins import ( "context" "fmt" - "strings" "github.com/gogo/protobuf/types" "github.com/google/uuid" @@ -19,15 +18,12 @@ import ( agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/sdk/v2/agent/events" "github.com/nginx/agent/sdk/v2/proto" - commonProto "github.com/nginx/agent/sdk/v2/proto/common" eventsProto "github.com/nginx/agent/sdk/v2/proto/events" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" ) const ( - AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" - AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" NGINX_FOUND_MESSAGE = "nginx-v%s master process was found with a pid %s" NGINX_STOP_MESSAGE = "nginx-v%s master process (pid: %s) stopped" NGINX_RELOAD_SUCCESS_MESSAGE = "nginx-v%s master process (pid: %s) reloaded successfully" @@ -41,12 +37,13 @@ const ( ) type Events struct { - pipeline core.MessagePipeInterface - ctx context.Context - conf *config.Config - env core.Environment - meta *proto.Metadata - nginxBinary core.NginxBinary + pipeline core.MessagePipeInterface + ctx context.Context + conf *config.Config + env core.Environment + meta *proto.Metadata + nginxBinary core.NginxBinary + agentEventsMeta *events.AgentEventMeta } func NewEvents(conf *config.Config, env core.Environment, meta *proto.Metadata, nginxBinary core.NginxBinary) *Events { @@ -118,23 +115,11 @@ func (a *Events) sendAgentStartedEvent(msg *core.Message) { return } - event := a.createAgentEvent( - types.TimestampNow(), - events.INFO_EVENT_LEVEL, - fmt.Sprintf(AGENT_START_MESSAGE, agentEventMeta.GetVersion(), a.env.GetHostname(), agentEventMeta.GetPid()), - uuid.NewString(), - ) + event := agentEventMeta.GenerateAgentStartEventCommand() log.Debugf("Created event: %v", event) - a.pipeline.Process(core.NewMessage(core.Events, &proto.Command{ - Meta: a.meta, - Type: proto.Command_NORMAL, - Data: &proto.Command_EventReport{ - EventReport: &eventsProto.EventReport{ - Events: []*eventsProto.Event{event}, - }, - }, - })) + a.pipeline.Process(core.NewMessage(core.Events, event)) + a.agentEventsMeta = agentEventMeta } func (a *Events) sendNingxFoundEvent(msg *core.Message) { @@ -409,7 +394,7 @@ func (a *Events) sendNginxWorkerStopEvent(msg *core.Message) { } func (e *Events) createNginxEvent(nginxId string, timestamp *types.Timestamp, level string, message string, correlationId string) *eventsProto.Event { - activityEvent := e.createActivityEvent(message, nginxId) + activityEvent := e.agentEventsMeta.CreateActivityEvent(message, nginxId) return &eventsProto.Event{ Metadata: &eventsProto.Metadata{ @@ -428,7 +413,7 @@ func (e *Events) createNginxEvent(nginxId string, timestamp *types.Timestamp, le } func (e *Events) createConfigApplyEvent(nginxId string, timestamp *types.Timestamp, level string, message string, correlationId string) *eventsProto.Event { - activityEvent := e.createActivityEvent(message, nginxId) + activityEvent := e.agentEventsMeta.CreateActivityEvent(message, nginxId) return &eventsProto.Event{ Metadata: &eventsProto.Metadata{ @@ -445,53 +430,3 @@ func (e *Events) createConfigApplyEvent(nginxId string, timestamp *types.Timesta }, } } - -func (e *Events) createAgentEvent(timestamp *types.Timestamp, level string, message string, correlationId string) *eventsProto.Event { - activityEvent := e.createActivityEvent(message, "") // blank nginxId, this relates to agent not it's nginx instances - - return &eventsProto.Event{ - Metadata: &eventsProto.Metadata{ - UUID: uuid.NewString(), - CorrelationID: correlationId, - Module: config.MODULE, - Timestamp: timestamp, - EventLevel: level, - Type: events.AGENT_EVENT_TYPE, - Category: events.STATUS_CATEGORY, - }, - Data: &eventsProto.Event_ActivityEvent{ - ActivityEvent: activityEvent, - }, - } -} - -func (e *Events) createActivityEvent(message string, nginxId string) *eventsProto.ActivityEvent { - activityEvent := &eventsProto.ActivityEvent{ - Message: message, - Dimensions: []*commonProto.Dimension{ - { - Name: "system_id", - Value: e.env.GetSystemUUID(), - }, - { - Name: "hostname", - Value: e.env.GetHostname(), - }, - { - Name: "instance_group", - Value: e.conf.InstanceGroup, - }, - { - Name: "system.tags", - Value: strings.Join(e.conf.Tags, ","), - }, - }, - } - - if nginxId != "" { - nginxDim := []*commonProto.Dimension{{Name: "nginx_id", Value: nginxId}} - activityEvent.Dimensions = append(nginxDim, activityEvent.Dimensions...) - } - - return activityEvent -} diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index a2a9b10e4..f85880faf 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -23,26 +23,26 @@ type AgentEventMeta struct { module string version string pid string - message string hostname string systemUuid string instanceGroup string - tags []string + tags string + tagsRaw []string } func NewAgentEventMeta( - module, version, pid, message, hostname, systemUuid, instanceGroup string, + module, version, pid, hostname, systemUuid, instanceGroup string, tags []string, ) *AgentEventMeta { return &AgentEventMeta{ module: module, version: version, pid: pid, - message: message, hostname: hostname, systemUuid: systemUuid, instanceGroup: instanceGroup, - tags: tags, + tagsRaw: tags, + tags: strings.Join(tags, ","), } } @@ -54,9 +54,58 @@ func (aem *AgentEventMeta) GetPid() string { return aem.pid } +func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { + activityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: aem.systemUuid, + }, + { + Name: "hostname", + Value: aem.hostname, + }, + { + Name: "instance_group", + Value: aem.instanceGroup, + }, + { + Name: "system.tags", + Value: aem.tags, + }, + }, + } + + event := &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: uuid.NewString(), + Module: aem.module, + Timestamp: types.TimestampNow(), + EventLevel: WARN_EVENT_LEVEL, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } + + return &proto.Command{ + Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), + Type: proto.Command_NORMAL, + Data: &proto.Command_EventReport{ + EventReport: &eventsProto.EventReport{ + Events: []*eventsProto.Event{event}, + }, + }, + } +} + func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", aem.message, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -72,7 +121,7 @@ func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { }, { Name: "system.tags", - Value: strings.Join(aem.tags, ","), + Value: aem.tags, }, }, } @@ -102,3 +151,54 @@ func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { }, } } + +func (aem *AgentEventMeta) CreateAgentEvent(timestamp *types.Timestamp, level, message, correlationId, module string) *eventsProto.Event { + activityEvent := aem.CreateActivityEvent(message, "") // blank nginxId, this relates to agent not it's nginx instances + + return &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: correlationId, + Module: module, + Timestamp: timestamp, + EventLevel: level, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } +} + +func (aem *AgentEventMeta) CreateActivityEvent(message string, nginxId string) *eventsProto.ActivityEvent { + activityEvent := &eventsProto.ActivityEvent{ + Message: message, + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: aem.systemUuid, + }, + { + Name: "hostname", + Value: aem.hostname, + }, + { + Name: "instance_group", + Value: aem.instanceGroup, + }, + { + Name: "system.tags", + Value: aem.tags, + }, + }, + } + + if nginxId != "" { + nginxDim := []*commonProto.Dimension{{Name: "nginx_id", Value: nginxId}} + activityEvent.Dimensions = append(nginxDim, activityEvent.Dimensions...) + } + + return activityEvent +} + diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go index 0340d130d..275abc2a0 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -16,4 +16,8 @@ const ( WARN_EVENT_LEVEL = "WARN" ERROR_EVENT_LEVEL = "ERROR" CRITICAL_EVENT_LEVEL = "CRITICAL" + + // Messages + AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" + AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" ) diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index a2a9b10e4..f85880faf 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -23,26 +23,26 @@ type AgentEventMeta struct { module string version string pid string - message string hostname string systemUuid string instanceGroup string - tags []string + tags string + tagsRaw []string } func NewAgentEventMeta( - module, version, pid, message, hostname, systemUuid, instanceGroup string, + module, version, pid, hostname, systemUuid, instanceGroup string, tags []string, ) *AgentEventMeta { return &AgentEventMeta{ module: module, version: version, pid: pid, - message: message, hostname: hostname, systemUuid: systemUuid, instanceGroup: instanceGroup, - tags: tags, + tagsRaw: tags, + tags: strings.Join(tags, ","), } } @@ -54,9 +54,58 @@ func (aem *AgentEventMeta) GetPid() string { return aem.pid } +func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { + activityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: aem.systemUuid, + }, + { + Name: "hostname", + Value: aem.hostname, + }, + { + Name: "instance_group", + Value: aem.instanceGroup, + }, + { + Name: "system.tags", + Value: aem.tags, + }, + }, + } + + event := &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: uuid.NewString(), + Module: aem.module, + Timestamp: types.TimestampNow(), + EventLevel: WARN_EVENT_LEVEL, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } + + return &proto.Command{ + Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), + Type: proto.Command_NORMAL, + Data: &proto.Command_EventReport{ + EventReport: &eventsProto.EventReport{ + Events: []*eventsProto.Event{event}, + }, + }, + } +} + func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", aem.message, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -72,7 +121,7 @@ func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { }, { Name: "system.tags", - Value: strings.Join(aem.tags, ","), + Value: aem.tags, }, }, } @@ -102,3 +151,54 @@ func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { }, } } + +func (aem *AgentEventMeta) CreateAgentEvent(timestamp *types.Timestamp, level, message, correlationId, module string) *eventsProto.Event { + activityEvent := aem.CreateActivityEvent(message, "") // blank nginxId, this relates to agent not it's nginx instances + + return &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: correlationId, + Module: module, + Timestamp: timestamp, + EventLevel: level, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } +} + +func (aem *AgentEventMeta) CreateActivityEvent(message string, nginxId string) *eventsProto.ActivityEvent { + activityEvent := &eventsProto.ActivityEvent{ + Message: message, + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: aem.systemUuid, + }, + { + Name: "hostname", + Value: aem.hostname, + }, + { + Name: "instance_group", + Value: aem.instanceGroup, + }, + { + Name: "system.tags", + Value: aem.tags, + }, + }, + } + + if nginxId != "" { + nginxDim := []*commonProto.Dimension{{Name: "nginx_id", Value: nginxId}} + activityEvent.Dimensions = append(nginxDim, activityEvent.Dimensions...) + } + + return activityEvent +} + diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go index 0340d130d..275abc2a0 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -16,4 +16,8 @@ const ( WARN_EVENT_LEVEL = "WARN" ERROR_EVENT_LEVEL = "ERROR" CRITICAL_EVENT_LEVEL = "CRITICAL" + + // Messages + AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" + AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" ) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go index 9c116982e..2c2fe2661 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go @@ -10,7 +10,6 @@ package plugins import ( "context" "fmt" - "strings" "github.com/gogo/protobuf/types" "github.com/google/uuid" @@ -19,15 +18,12 @@ import ( agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/sdk/v2/agent/events" "github.com/nginx/agent/sdk/v2/proto" - commonProto "github.com/nginx/agent/sdk/v2/proto/common" eventsProto "github.com/nginx/agent/sdk/v2/proto/events" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" ) const ( - AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" - AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" NGINX_FOUND_MESSAGE = "nginx-v%s master process was found with a pid %s" NGINX_STOP_MESSAGE = "nginx-v%s master process (pid: %s) stopped" NGINX_RELOAD_SUCCESS_MESSAGE = "nginx-v%s master process (pid: %s) reloaded successfully" @@ -41,12 +37,13 @@ const ( ) type Events struct { - pipeline core.MessagePipeInterface - ctx context.Context - conf *config.Config - env core.Environment - meta *proto.Metadata - nginxBinary core.NginxBinary + pipeline core.MessagePipeInterface + ctx context.Context + conf *config.Config + env core.Environment + meta *proto.Metadata + nginxBinary core.NginxBinary + agentEventsMeta *events.AgentEventMeta } func NewEvents(conf *config.Config, env core.Environment, meta *proto.Metadata, nginxBinary core.NginxBinary) *Events { @@ -118,23 +115,11 @@ func (a *Events) sendAgentStartedEvent(msg *core.Message) { return } - event := a.createAgentEvent( - types.TimestampNow(), - events.INFO_EVENT_LEVEL, - fmt.Sprintf(AGENT_START_MESSAGE, agentEventMeta.GetVersion(), a.env.GetHostname(), agentEventMeta.GetPid()), - uuid.NewString(), - ) + event := agentEventMeta.GenerateAgentStartEventCommand() log.Debugf("Created event: %v", event) - a.pipeline.Process(core.NewMessage(core.Events, &proto.Command{ - Meta: a.meta, - Type: proto.Command_NORMAL, - Data: &proto.Command_EventReport{ - EventReport: &eventsProto.EventReport{ - Events: []*eventsProto.Event{event}, - }, - }, - })) + a.pipeline.Process(core.NewMessage(core.Events, event)) + a.agentEventsMeta = agentEventMeta } func (a *Events) sendNingxFoundEvent(msg *core.Message) { @@ -409,7 +394,7 @@ func (a *Events) sendNginxWorkerStopEvent(msg *core.Message) { } func (e *Events) createNginxEvent(nginxId string, timestamp *types.Timestamp, level string, message string, correlationId string) *eventsProto.Event { - activityEvent := e.createActivityEvent(message, nginxId) + activityEvent := e.agentEventsMeta.CreateActivityEvent(message, nginxId) return &eventsProto.Event{ Metadata: &eventsProto.Metadata{ @@ -428,7 +413,7 @@ func (e *Events) createNginxEvent(nginxId string, timestamp *types.Timestamp, le } func (e *Events) createConfigApplyEvent(nginxId string, timestamp *types.Timestamp, level string, message string, correlationId string) *eventsProto.Event { - activityEvent := e.createActivityEvent(message, nginxId) + activityEvent := e.agentEventsMeta.CreateActivityEvent(message, nginxId) return &eventsProto.Event{ Metadata: &eventsProto.Metadata{ @@ -445,53 +430,3 @@ func (e *Events) createConfigApplyEvent(nginxId string, timestamp *types.Timesta }, } } - -func (e *Events) createAgentEvent(timestamp *types.Timestamp, level string, message string, correlationId string) *eventsProto.Event { - activityEvent := e.createActivityEvent(message, "") // blank nginxId, this relates to agent not it's nginx instances - - return &eventsProto.Event{ - Metadata: &eventsProto.Metadata{ - UUID: uuid.NewString(), - CorrelationID: correlationId, - Module: config.MODULE, - Timestamp: timestamp, - EventLevel: level, - Type: events.AGENT_EVENT_TYPE, - Category: events.STATUS_CATEGORY, - }, - Data: &eventsProto.Event_ActivityEvent{ - ActivityEvent: activityEvent, - }, - } -} - -func (e *Events) createActivityEvent(message string, nginxId string) *eventsProto.ActivityEvent { - activityEvent := &eventsProto.ActivityEvent{ - Message: message, - Dimensions: []*commonProto.Dimension{ - { - Name: "system_id", - Value: e.env.GetSystemUUID(), - }, - { - Name: "hostname", - Value: e.env.GetHostname(), - }, - { - Name: "instance_group", - Value: e.conf.InstanceGroup, - }, - { - Name: "system.tags", - Value: strings.Join(e.conf.Tags, ","), - }, - }, - } - - if nginxId != "" { - nginxDim := []*commonProto.Dimension{{Name: "nginx_id", Value: nginxId}} - activityEvent.Dimensions = append(nginxDim, activityEvent.Dimensions...) - } - - return activityEvent -} diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index a2a9b10e4..f85880faf 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -23,26 +23,26 @@ type AgentEventMeta struct { module string version string pid string - message string hostname string systemUuid string instanceGroup string - tags []string + tags string + tagsRaw []string } func NewAgentEventMeta( - module, version, pid, message, hostname, systemUuid, instanceGroup string, + module, version, pid, hostname, systemUuid, instanceGroup string, tags []string, ) *AgentEventMeta { return &AgentEventMeta{ module: module, version: version, pid: pid, - message: message, hostname: hostname, systemUuid: systemUuid, instanceGroup: instanceGroup, - tags: tags, + tagsRaw: tags, + tags: strings.Join(tags, ","), } } @@ -54,9 +54,58 @@ func (aem *AgentEventMeta) GetPid() string { return aem.pid } +func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { + activityEvent := &eventsProto.ActivityEvent{ + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: aem.systemUuid, + }, + { + Name: "hostname", + Value: aem.hostname, + }, + { + Name: "instance_group", + Value: aem.instanceGroup, + }, + { + Name: "system.tags", + Value: aem.tags, + }, + }, + } + + event := &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: uuid.NewString(), + Module: aem.module, + Timestamp: types.TimestampNow(), + EventLevel: WARN_EVENT_LEVEL, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } + + return &proto.Command{ + Meta: sdkGRPC.NewMessageMeta(uuid.NewString()), + Type: proto.Command_NORMAL, + Data: &proto.Command_EventReport{ + EventReport: &eventsProto.EventReport{ + Events: []*eventsProto.Event{event}, + }, + }, + } +} + func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf("%s %s (pid: %s) stopped on %s", aem.message, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -72,7 +121,7 @@ func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { }, { Name: "system.tags", - Value: strings.Join(aem.tags, ","), + Value: aem.tags, }, }, } @@ -102,3 +151,54 @@ func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { }, } } + +func (aem *AgentEventMeta) CreateAgentEvent(timestamp *types.Timestamp, level, message, correlationId, module string) *eventsProto.Event { + activityEvent := aem.CreateActivityEvent(message, "") // blank nginxId, this relates to agent not it's nginx instances + + return &eventsProto.Event{ + Metadata: &eventsProto.Metadata{ + UUID: uuid.NewString(), + CorrelationID: correlationId, + Module: module, + Timestamp: timestamp, + EventLevel: level, + Type: AGENT_EVENT_TYPE, + Category: STATUS_CATEGORY, + }, + Data: &eventsProto.Event_ActivityEvent{ + ActivityEvent: activityEvent, + }, + } +} + +func (aem *AgentEventMeta) CreateActivityEvent(message string, nginxId string) *eventsProto.ActivityEvent { + activityEvent := &eventsProto.ActivityEvent{ + Message: message, + Dimensions: []*commonProto.Dimension{ + { + Name: "system_id", + Value: aem.systemUuid, + }, + { + Name: "hostname", + Value: aem.hostname, + }, + { + Name: "instance_group", + Value: aem.instanceGroup, + }, + { + Name: "system.tags", + Value: aem.tags, + }, + }, + } + + if nginxId != "" { + nginxDim := []*commonProto.Dimension{{Name: "nginx_id", Value: nginxId}} + activityEvent.Dimensions = append(nginxDim, activityEvent.Dimensions...) + } + + return activityEvent +} + diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go index 0340d130d..275abc2a0 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -16,4 +16,8 @@ const ( WARN_EVENT_LEVEL = "WARN" ERROR_EVENT_LEVEL = "ERROR" CRITICAL_EVENT_LEVEL = "CRITICAL" + + // Messages + AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" + AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" ) From 5ffca9671a31e3557e0d4dfc92c2d2befecf1e75 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Thu, 7 Sep 2023 15:40:54 +0100 Subject: [PATCH 16/20] move agent meta --- sdk/agent/events/meta.go | 7 +++---- sdk/agent/events/types.go | 4 ++-- src/core/signals.go | 4 ++-- src/plugins/events.go | 12 ++++++------ .../nginx/agent/sdk/v2/agent/events/meta.go | 7 +++---- .../nginx/agent/sdk/v2/agent/events/types.go | 4 ++-- .../github.com/nginx/agent/v2/src/core/signals.go | 4 ++-- .../nginx/agent/sdk/v2/agent/events/meta.go | 7 +++---- .../nginx/agent/sdk/v2/agent/events/types.go | 4 ++-- .../github.com/nginx/agent/v2/src/core/signals.go | 4 ++-- .../github.com/nginx/agent/v2/src/plugins/events.go | 12 ++++++------ .../nginx/agent/sdk/v2/agent/events/meta.go | 7 +++---- .../nginx/agent/sdk/v2/agent/events/types.go | 4 ++-- 13 files changed, 38 insertions(+), 42 deletions(-) diff --git a/sdk/agent/events/meta.go b/sdk/agent/events/meta.go index f85880faf..523f7024d 100644 --- a/sdk/agent/events/meta.go +++ b/sdk/agent/events/meta.go @@ -26,7 +26,7 @@ type AgentEventMeta struct { hostname string systemUuid string instanceGroup string - tags string + tags string tagsRaw []string } @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -105,7 +105,7 @@ func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -201,4 +201,3 @@ func (aem *AgentEventMeta) CreateActivityEvent(message string, nginxId string) * return activityEvent } - diff --git a/sdk/agent/events/types.go b/sdk/agent/events/types.go index 275abc2a0..8f55f5d34 100644 --- a/sdk/agent/events/types.go +++ b/sdk/agent/events/types.go @@ -18,6 +18,6 @@ const ( CRITICAL_EVENT_LEVEL = "CRITICAL" // Messages - AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" - AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" + AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" + AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" ) diff --git a/src/core/signals.go b/src/core/signals.go index 8d6e7e34a..c8a1ed8d8 100644 --- a/src/core/signals.go +++ b/src/core/signals.go @@ -38,10 +38,10 @@ func HandleSignals( go func() { select { case <-sigChan: - event := events.NewAgentEventMeta(config.MODULE, + event := events.NewAgentEventMeta( + config.MODULE, version, strconv.Itoa(os.Getpid()), - "Initialize Agent", env.GetHostname(), env.GetSystemUUID(), loadedConfig.InstanceGroup, diff --git a/src/plugins/events.go b/src/plugins/events.go index 2c2fe2661..56404ce31 100644 --- a/src/plugins/events.go +++ b/src/plugins/events.go @@ -37,12 +37,12 @@ const ( ) type Events struct { - pipeline core.MessagePipeInterface - ctx context.Context - conf *config.Config - env core.Environment - meta *proto.Metadata - nginxBinary core.NginxBinary + pipeline core.MessagePipeInterface + ctx context.Context + conf *config.Config + env core.Environment + meta *proto.Metadata + nginxBinary core.NginxBinary agentEventsMeta *events.AgentEventMeta } diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index f85880faf..523f7024d 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -26,7 +26,7 @@ type AgentEventMeta struct { hostname string systemUuid string instanceGroup string - tags string + tags string tagsRaw []string } @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -105,7 +105,7 @@ func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -201,4 +201,3 @@ func (aem *AgentEventMeta) CreateActivityEvent(message string, nginxId string) * return activityEvent } - diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go index 275abc2a0..8f55f5d34 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -18,6 +18,6 @@ const ( CRITICAL_EVENT_LEVEL = "CRITICAL" // Messages - AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" - AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" + AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" + AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" ) diff --git a/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go b/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go index 8d6e7e34a..c8a1ed8d8 100644 --- a/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go +++ b/test/integration/vendor/github.com/nginx/agent/v2/src/core/signals.go @@ -38,10 +38,10 @@ func HandleSignals( go func() { select { case <-sigChan: - event := events.NewAgentEventMeta(config.MODULE, + event := events.NewAgentEventMeta( + config.MODULE, version, strconv.Itoa(os.Getpid()), - "Initialize Agent", env.GetHostname(), env.GetSystemUUID(), loadedConfig.InstanceGroup, diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index f85880faf..523f7024d 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -26,7 +26,7 @@ type AgentEventMeta struct { hostname string systemUuid string instanceGroup string - tags string + tags string tagsRaw []string } @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -105,7 +105,7 @@ func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -201,4 +201,3 @@ func (aem *AgentEventMeta) CreateActivityEvent(message string, nginxId string) * return activityEvent } - diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go index 275abc2a0..8f55f5d34 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -18,6 +18,6 @@ const ( CRITICAL_EVENT_LEVEL = "CRITICAL" // Messages - AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" - AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" + AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" + AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" ) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go index 8d6e7e34a..c8a1ed8d8 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/signals.go @@ -38,10 +38,10 @@ func HandleSignals( go func() { select { case <-sigChan: - event := events.NewAgentEventMeta(config.MODULE, + event := events.NewAgentEventMeta( + config.MODULE, version, strconv.Itoa(os.Getpid()), - "Initialize Agent", env.GetHostname(), env.GetSystemUUID(), loadedConfig.InstanceGroup, diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go index 2c2fe2661..56404ce31 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/events.go @@ -37,12 +37,12 @@ const ( ) type Events struct { - pipeline core.MessagePipeInterface - ctx context.Context - conf *config.Config - env core.Environment - meta *proto.Metadata - nginxBinary core.NginxBinary + pipeline core.MessagePipeInterface + ctx context.Context + conf *config.Config + env core.Environment + meta *proto.Metadata + nginxBinary core.NginxBinary agentEventsMeta *events.AgentEventMeta } diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index f85880faf..523f7024d 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -26,7 +26,7 @@ type AgentEventMeta struct { hostname string systemUuid string instanceGroup string - tags string + tags string tagsRaw []string } @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -105,7 +105,7 @@ func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { func (aem *AgentEventMeta) GenerateAgentStopEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_STOP_MESSAGE, aem.version, aem.pid, aem.hostname), Dimensions: []*commonProto.Dimension{ { Name: "system_id", @@ -201,4 +201,3 @@ func (aem *AgentEventMeta) CreateActivityEvent(message string, nginxId string) * return activityEvent } - diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go index 275abc2a0..8f55f5d34 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/types.go @@ -18,6 +18,6 @@ const ( CRITICAL_EVENT_LEVEL = "CRITICAL" // Messages - AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" - AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" + AGENT_START_MESSAGE = "nginx-agent %s started on %s with pid %s" + AGENT_STOP_MESSAGE = "nginx-agent %s (pid: %s) stopped on %s" ) From 1a390e5f9bec8d767072a8246496bb3bb00f0ada Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Thu, 7 Sep 2023 17:31:02 +0100 Subject: [PATCH 17/20] fixed tests --- main.go | 4 +- sdk/agent/events/meta.go | 2 +- src/plugins/events_test.go | 70 ++++++++++++++++--- .../nginx/agent/sdk/v2/agent/events/meta.go | 2 +- .../nginx/agent/sdk/v2/agent/events/meta.go | 2 +- .../nginx/agent/sdk/v2/agent/events/meta.go | 2 +- 6 files changed, 67 insertions(+), 15 deletions(-) diff --git a/main.go b/main.go index a52c0f4e4..eea2e7d0c 100644 --- a/main.go +++ b/main.go @@ -79,10 +79,10 @@ func main() { pipe := core.InitializePipe(ctx, corePlugins, extensionPlugins, agent_config.DefaultPluginSize) - event := events.NewAgentEventMeta(config.MODULE, + event := events.NewAgentEventMeta( + config.MODULE, version, strconv.Itoa(os.Getpid()), - "Initialize Agent", env.GetHostname(), env.GetSystemUUID(), loadedConfig.InstanceGroup, diff --git a/sdk/agent/events/meta.go b/sdk/agent/events/meta.go index 523f7024d..a6943f3a4 100644 --- a/sdk/agent/events/meta.go +++ b/sdk/agent/events/meta.go @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.hostname, aem.pid), Dimensions: []*commonProto.Dimension{ { Name: "system_id", diff --git a/src/plugins/events_test.go b/src/plugins/events_test.go index cf491e122..4e1234780 100644 --- a/src/plugins/events_test.go +++ b/src/plugins/events_test.go @@ -63,8 +63,10 @@ func TestActivityEvents_Process(t *testing.T) { name: "test NginxInstancesFound message", message: core.NewMessage(core.NginxInstancesFound, tutils.GetDetailsMap()), msgTopics: []string{ + core.AgentStarted, core.NginxInstancesFound, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -94,8 +96,10 @@ func TestActivityEvents_Process(t *testing.T) { correlationId: uuid.NewString(), }), msgTopics: []string{ + core.AgentStarted, core.NginxReloadComplete, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -124,8 +128,10 @@ func TestActivityEvents_Process(t *testing.T) { correlationId: uuid.NewString(), }), msgTopics: []string{ + core.AgentStarted, core.NginxReloadComplete, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -161,8 +167,10 @@ func TestActivityEvents_Process(t *testing.T) { }, }), msgTopics: []string{ + core.AgentStarted, core.CommResponse, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -198,8 +206,10 @@ func TestActivityEvents_Process(t *testing.T) { }, }), msgTopics: []string{ + core.AgentStarted, core.CommResponse, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -235,8 +245,10 @@ func TestActivityEvents_Process(t *testing.T) { }, }), msgTopics: []string{ + core.AgentStarted, core.CommResponse, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -270,7 +282,9 @@ func TestActivityEvents_Process(t *testing.T) { }, }), msgTopics: []string{ + core.AgentStarted, core.CommResponse, + core.Events, }, expectedEventReport: nil, }, @@ -282,8 +296,10 @@ func TestActivityEvents_Process(t *testing.T) { correlationId: uuid.NewString(), }), msgTopics: []string{ + core.AgentStarted, core.ConfigRollbackResponse, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -312,8 +328,10 @@ func TestActivityEvents_Process(t *testing.T) { correlationId: uuid.NewString(), }), msgTopics: []string{ + core.AgentStarted, core.ConfigRollbackResponse, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -340,11 +358,10 @@ func TestActivityEvents_Process(t *testing.T) { config.MODULE, "v0.0.1", "75231", - "nginx-agent v0.0.1 started on test-host with pid 75231", - "", - "", - "", - []string{}, + "test-host", + "12345678", + "group-a", + []string{"tag-a","tag-b"}, )), msgTopics: []string{ core.AgentStarted, @@ -373,8 +390,10 @@ func TestActivityEvents_Process(t *testing.T) { name: "test NginxMasterProcCreated message", message: core.NewMessage(core.NginxMasterProcCreated, &proto.NginxDetails{Version: "1.0.1", ProcessId: "75231"}), msgTopics: []string{ + core.AgentStarted, core.NginxMasterProcCreated, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -399,8 +418,10 @@ func TestActivityEvents_Process(t *testing.T) { name: "test NginxMasterProcKilled message", message: core.NewMessage(core.NginxMasterProcKilled, &proto.NginxDetails{Version: "1.0.1", ProcessId: "75231"}), msgTopics: []string{ + core.AgentStarted, core.NginxMasterProcKilled, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -425,8 +446,10 @@ func TestActivityEvents_Process(t *testing.T) { name: "test NginxWorkerProcCreated message", message: core.NewMessage(core.NginxWorkerProcCreated, &proto.NginxDetails{Version: "1.0.1", ProcessId: "75231"}), msgTopics: []string{ + core.AgentStarted, core.NginxWorkerProcCreated, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -451,8 +474,10 @@ func TestActivityEvents_Process(t *testing.T) { name: "test NginxWorkerProcKilled message", message: core.NewMessage(core.NginxWorkerProcKilled, &proto.NginxDetails{Version: "1.0.1", ProcessId: "75231"}), msgTopics: []string{ + core.AgentStarted, core.NginxWorkerProcKilled, core.Events, + core.Events, }, expectedEventReport: &eventsProto.EventReport{ Events: []*eventsProto.Event{ @@ -477,7 +502,9 @@ func TestActivityEvents_Process(t *testing.T) { name: "test unknown message", message: core.NewMessage(core.UNKNOWN, "unknown message"), msgTopics: []string{ + core.AgentStarted, core.UNKNOWN, + core.Events, }, }, } @@ -507,9 +534,21 @@ func TestActivityEvents_Process(t *testing.T) { } pluginUnderTest := NewEvents(config, env, grpc.NewMessageMeta(uuid.New().String()), core.NewNginxBinary(env, config)) - messagePipe := core.SetupMockMessagePipe(t, ctx, []core.Plugin{pluginUnderTest}, []core.ExtensionPlugin{}) - + + if test.name != "test AgentStart message" { + agentMeta := events.NewAgentEventMeta( + "NGINX-AGENT", + "v0.0.1", + "75231", + "test-host", + "12345678", + "group-a", + []string{"tag-a","tag-b"}) + + messagePipe.Process(core.NewMessage(core.AgentStarted, agentMeta)) + } + messagePipe.Process(test.message) messagePipe.Run() time.Sleep(250 * time.Millisecond) @@ -523,9 +562,23 @@ func TestActivityEvents_Process(t *testing.T) { tt.Errorf("unexpected message topic: %s :: should have been: %s", msg.Topic(), test.msgTopics[idx]) } if test.expectedEventReport != nil && msg.Exact(core.Events) { - expectedEvent := test.expectedEventReport.Events[0] + var expectedEvent *eventsProto.Event + if (len(test.expectedEventReport.GetEvents()) == 1) { + expectedEvent = test.expectedEventReport.Events[0] + + } else { + // get the latest event + events := test.expectedEventReport.Events[:len(test.expectedEventReport.GetEvents())-1] + expectedEvent = events[0] + } actualEvent := msg.Data().(*proto.Command).GetEventReport().Events[0] + if (actualEvent.GetMetadata().GetType() != expectedEvent.GetMetadata().GetType() || + actualEvent.GetMetadata().GetCategory() != expectedEvent.GetMetadata().GetCategory() || + actualEvent.GetMetadata().GetEventLevel() != expectedEvent.GetMetadata().GetEventLevel()) { + continue + } + // assert metadata assert.Equal(tt, expectedEvent.Metadata.Module, actualEvent.Metadata.Module) assert.Equal(tt, expectedEvent.Metadata.Category, actualEvent.Metadata.Category) @@ -611,7 +664,6 @@ func TestGenerateAgentStopEvent(t *testing.T) { config.MODULE, tt.agentVersion, tt.pid, - "nginx-agent", env.GetHostname(), env.GetSystemUUID(), tt.conf.InstanceGroup, diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 523f7024d..a6943f3a4 100644 --- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/integration/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.hostname, aem.pid), Dimensions: []*commonProto.Dimension{ { Name: "system_id", diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 523f7024d..a6943f3a4 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.hostname, aem.pid), Dimensions: []*commonProto.Dimension{ { Name: "system_id", diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go index 523f7024d..a6943f3a4 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/events/meta.go @@ -56,7 +56,7 @@ func (aem *AgentEventMeta) GetPid() string { func (aem *AgentEventMeta) GenerateAgentStartEventCommand() *proto.Command { activityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.pid, aem.hostname), + Message: fmt.Sprintf(AGENT_START_MESSAGE, aem.version, aem.hostname, aem.pid), Dimensions: []*commonProto.Dimension{ { Name: "system_id", From 536b411b57098d6ac5033c258332f2ec21d9c2ec Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Thu, 7 Sep 2023 17:31:53 +0100 Subject: [PATCH 18/20] format --- src/plugins/events_test.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/plugins/events_test.go b/src/plugins/events_test.go index 4e1234780..be36f134c 100644 --- a/src/plugins/events_test.go +++ b/src/plugins/events_test.go @@ -361,7 +361,7 @@ func TestActivityEvents_Process(t *testing.T) { "test-host", "12345678", "group-a", - []string{"tag-a","tag-b"}, + []string{"tag-a", "tag-b"}, )), msgTopics: []string{ core.AgentStarted, @@ -535,7 +535,7 @@ func TestActivityEvents_Process(t *testing.T) { pluginUnderTest := NewEvents(config, env, grpc.NewMessageMeta(uuid.New().String()), core.NewNginxBinary(env, config)) messagePipe := core.SetupMockMessagePipe(t, ctx, []core.Plugin{pluginUnderTest}, []core.ExtensionPlugin{}) - + if test.name != "test AgentStart message" { agentMeta := events.NewAgentEventMeta( "NGINX-AGENT", @@ -544,11 +544,11 @@ func TestActivityEvents_Process(t *testing.T) { "test-host", "12345678", "group-a", - []string{"tag-a","tag-b"}) - + []string{"tag-a", "tag-b"}) + messagePipe.Process(core.NewMessage(core.AgentStarted, agentMeta)) } - + messagePipe.Process(test.message) messagePipe.Run() time.Sleep(250 * time.Millisecond) @@ -563,19 +563,18 @@ func TestActivityEvents_Process(t *testing.T) { } if test.expectedEventReport != nil && msg.Exact(core.Events) { var expectedEvent *eventsProto.Event - if (len(test.expectedEventReport.GetEvents()) == 1) { + if len(test.expectedEventReport.GetEvents()) == 1 { expectedEvent = test.expectedEventReport.Events[0] - } else { // get the latest event - events := test.expectedEventReport.Events[:len(test.expectedEventReport.GetEvents())-1] + events := test.expectedEventReport.Events[:len(test.expectedEventReport.GetEvents())-1] expectedEvent = events[0] } actualEvent := msg.Data().(*proto.Command).GetEventReport().Events[0] - if (actualEvent.GetMetadata().GetType() != expectedEvent.GetMetadata().GetType() || + if actualEvent.GetMetadata().GetType() != expectedEvent.GetMetadata().GetType() || actualEvent.GetMetadata().GetCategory() != expectedEvent.GetMetadata().GetCategory() || - actualEvent.GetMetadata().GetEventLevel() != expectedEvent.GetMetadata().GetEventLevel()) { + actualEvent.GetMetadata().GetEventLevel() != expectedEvent.GetMetadata().GetEventLevel() { continue } From e6bc3583ed63e57c28e16171e876fe18ca22f370 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Thu, 7 Sep 2023 17:41:32 +0100 Subject: [PATCH 19/20] local changes --- .../vendor/github.com/nginx/agent/v2/src/plugins/common.go | 7 +++++++ vendor/github.com/nginx/agent/sdk/v2/config_helpers.go | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/common.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/common.go index 727ff0e73..045fa1709 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/common.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/common.go @@ -99,6 +99,13 @@ func LoadPlugins(commander client.Commander, binary core.NginxBinary, env core.E } else { extensionPlugins = append(extensionPlugins, nginxAppProtectMonitoringExtensionPlugin) } + case extension == agent_config.PhpFpmMetricsExtensionPlugin: + phpFpmMetricstExtensionPlugin, err := extensions.NewPhpFpmMetrics(env, loadedConfig) + if err != nil { + log.Errorf("Unable to load the PhpFpm Metrics plugin due to the following error: %v", err) + } else { + extensionPlugins = append(extensionPlugins, phpFpmMetricstExtensionPlugin) + } default: log.Warnf("unknown extension configured: %s", extension) } diff --git a/vendor/github.com/nginx/agent/sdk/v2/config_helpers.go b/vendor/github.com/nginx/agent/sdk/v2/config_helpers.go index 95a30461e..8ad40b98c 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/config_helpers.go +++ b/vendor/github.com/nginx/agent/sdk/v2/config_helpers.go @@ -25,14 +25,13 @@ import ( "strings" "time" - log "github.com/sirupsen/logrus" - "github.com/nginx/agent/sdk/v2/backoff" filesSDK "github.com/nginx/agent/sdk/v2/files" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/sdk/v2/zip" crossplane "github.com/nginxinc/nginx-go-crossplane" + log "github.com/sirupsen/logrus" ) const ( From 16638ae1b4b45c6f3d9d31ff76bd2b8ad2e69c41 Mon Sep 17 00:00:00 2001 From: Oliver O'Mahony Date: Thu, 7 Sep 2023 18:31:23 +0100 Subject: [PATCH 20/20] local changes --- sdk/agent/events/meta_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/agent/events/meta_test.go b/sdk/agent/events/meta_test.go index 6674e4db9..40854f436 100644 --- a/sdk/agent/events/meta_test.go +++ b/sdk/agent/events/meta_test.go @@ -30,7 +30,8 @@ func TestNewAgentEventMeta(t *testing.T) { assert.Equal(t, hostname, meta.hostname) assert.Equal(t, systemUuid, meta.systemUuid) assert.Equal(t, instanceGroup, meta.instanceGroup) - assert.Equal(t, tags, meta.tags) + assert.Equal(t, tags, meta.tagsRaw) + assert.Equal(t, strings.Join(tags, ","), meta.tags) } func TestGenerateAgentStartEventCommand(t *testing.T) { @@ -45,7 +46,7 @@ func TestGenerateAgentStartEventCommand(t *testing.T) { ) expectedActivityEvent := &eventsProto.ActivityEvent{ - Message: fmt.Sprintf("%s %s started on %s with pid %s", "nginx-agent", "v2.0", "54321", "test-host"), + Message: fmt.Sprintf("%s %s started on %s with pid %s", "nginx-agent", "v2.0", "test-host", "54321"), Dimensions: []*commonProto.Dimension{ { Name: "system_id",