diff --git a/internal/command/command_plugin.go b/internal/command/command_plugin.go index ed3cc9ee8..c0ab74660 100644 --- a/internal/command/command_plugin.go +++ b/internal/command/command_plugin.go @@ -14,10 +14,10 @@ import ( mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/bus" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/grpc" "github.com/nginx/agent/v3/internal/logger" pkgConfig "github.com/nginx/agent/v3/pkg/config" - "github.com/nginx/agent/v3/pkg/uuid" ) var _ bus.Plugin = (*CommandPlugin)(nil) @@ -248,7 +248,7 @@ func (cp *CommandPlugin) createDataPlaneResponse(correlationID string, status mp ) *mpi.DataPlaneResponse { return &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, diff --git a/internal/command/command_service.go b/internal/command/command_service.go index 3f91ea634..5c991e76d 100644 --- a/internal/command/command_service.go +++ b/internal/command/command_service.go @@ -17,9 +17,10 @@ import ( mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/grpc" "github.com/nginx/agent/v3/internal/logger" - "github.com/nginx/agent/v3/pkg/uuid" + "google.golang.org/protobuf/types/known/timestamppb" backoffHelpers "github.com/nginx/agent/v3/internal/backoff" @@ -87,7 +88,7 @@ func (cs *CommandService) UpdateDataPlaneStatus( request := &mpi.UpdateDataPlaneStatusRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, @@ -137,7 +138,7 @@ func (cs *CommandService) UpdateDataPlaneHealth(ctx context.Context, instanceHea request := &mpi.UpdateDataPlaneHealthRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, @@ -215,7 +216,7 @@ func (cs *CommandService) CreateConnection( request := &mpi.CreateConnectionRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, diff --git a/internal/datasource/proto/message.go b/internal/datasource/proto/message.go new file mode 100644 index 000000000..a0b02123c --- /dev/null +++ b/internal/datasource/proto/message.go @@ -0,0 +1,23 @@ +// 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 proto + +import ( + "log/slog" + "time" + + "github.com/nginx/agent/v3/pkg/uuid" +) + +func GenerateMessageID() string { + uuidv7, err := uuid.GenerateUUIDV7() + if err != nil { + slog.Debug("issue generating uuidv7, using sha256 and timestamp instead", "error", err) + return uuid.Generate("%s", time.Now().String()) + } + + return uuidv7 +} diff --git a/internal/file/file_manager_service.go b/internal/file/file_manager_service.go index 5ffb4b880..cc55f9876 100644 --- a/internal/file/file_manager_service.go +++ b/internal/file/file_manager_service.go @@ -14,6 +14,7 @@ import ( "sync" "sync/atomic" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/model" "github.com/cenkalti/backoff/v4" @@ -23,7 +24,6 @@ import ( "github.com/nginx/agent/v3/internal/grpc" "github.com/nginx/agent/v3/internal/logger" "github.com/nginx/agent/v3/pkg/files" - "github.com/nginx/agent/v3/pkg/uuid" "google.golang.org/protobuf/types/known/timestamppb" backoffHelpers "github.com/nginx/agent/v3/internal/backoff" @@ -97,7 +97,7 @@ func (fms *FileManagerService) UpdateOverview( request := &mpi.UpdateOverviewRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: requestCorrelationID.Value.String(), Timestamp: timestamppb.Now(), }, @@ -169,7 +169,7 @@ func (fms *FileManagerService) UpdateFile( Contents: contents, }, MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, @@ -326,7 +326,7 @@ func (fms *FileManagerService) fileUpdate(ctx context.Context, file *mpi.File) e getFile := func() (*mpi.GetFileResponse, error) { return fms.fileServiceClient.GetFile(ctx, &mpi.GetFileRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: logger.GetCorrelationID(ctx), Timestamp: timestamppb.Now(), }, diff --git a/internal/file/file_plugin.go b/internal/file/file_plugin.go index ea73f8147..1b9356548 100644 --- a/internal/file/file_plugin.go +++ b/internal/file/file_plugin.go @@ -11,11 +11,11 @@ import ( "log/slog" "github.com/nginx/agent/v3/pkg/files" - "github.com/nginx/agent/v3/pkg/uuid" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/bus" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/grpc" "github.com/nginx/agent/v3/internal/logger" "github.com/nginx/agent/v3/internal/model" @@ -319,7 +319,7 @@ func (fp *FilePlugin) handleConfigUploadRequest(ctx context.Context, msg *bus.Me response := &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, @@ -343,7 +343,7 @@ func (fp *FilePlugin) createDataPlaneResponse(correlationID string, status mpi.C ) *mpi.DataPlaneResponse { return &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, diff --git a/internal/file/file_plugin_test.go b/internal/file/file_plugin_test.go index d0d5add6c..27c29949b 100644 --- a/internal/file/file_plugin_test.go +++ b/internal/file/file_plugin_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/nginx/agent/v3/internal/bus/busfakes" + "github.com/nginx/agent/v3/internal/datasource/proto" "google.golang.org/protobuf/types/known/timestamppb" @@ -23,7 +24,6 @@ import ( "github.com/nginx/agent/v3/internal/grpc/grpcfakes" "github.com/nginx/agent/v3/internal/model" "github.com/nginx/agent/v3/pkg/files" - "github.com/nginx/agent/v3/pkg/uuid" "github.com/nginx/agent/v3/test/helpers" "github.com/nginx/agent/v3/test/protos" "github.com/nginx/agent/v3/test/types" @@ -441,7 +441,7 @@ func TestFilePlugin_Process_ConfigApplyRollbackCompleteTopic(t *testing.T) { expectedResponse := &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", Timestamp: timestamppb.Now(), }, diff --git a/internal/logger/logger.go b/internal/logger/logger.go index f6ba3af95..ec7491f52 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -14,7 +14,7 @@ import ( "strings" "github.com/nginx/agent/v3/internal/config" - "github.com/nginx/agent/v3/pkg/uuid" + "github.com/nginx/agent/v3/internal/datasource/proto" ) const ( @@ -121,7 +121,7 @@ func (h contextHandler) observe(ctx context.Context) (as []slog.Attr) { } func GenerateCorrelationID() slog.Attr { - return slog.Any(CorrelationIDKey, uuid.GenerateUUIDV7()) + return slog.Any(CorrelationIDKey, proto.GenerateMessageID()) } func GetCorrelationID(ctx context.Context) string { diff --git a/internal/resource/resource_plugin.go b/internal/resource/resource_plugin.go index f6262fa7b..a2c05ae65 100644 --- a/internal/resource/resource_plugin.go +++ b/internal/resource/resource_plugin.go @@ -10,8 +10,8 @@ import ( "log/slog" "github.com/nginx/agent/v3/internal/config" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/internal/model" - "github.com/nginx/agent/v3/pkg/uuid" "google.golang.org/protobuf/types/known/timestamppb" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" @@ -186,7 +186,7 @@ func (*Resource) createDataPlaneResponse(correlationID string, status mpi.Comman ) *mpi.DataPlaneResponse { return &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: correlationID, Timestamp: timestamppb.Now(), }, diff --git a/internal/watcher/watcher_plugin_test.go b/internal/watcher/watcher_plugin_test.go index b92d44888..427b76af2 100644 --- a/internal/watcher/watcher_plugin_test.go +++ b/internal/watcher/watcher_plugin_test.go @@ -11,7 +11,7 @@ import ( "time" "github.com/nginx/agent/v3/internal/bus/busfakes" - "github.com/nginx/agent/v3/pkg/uuid" + "github.com/nginx/agent/v3/internal/datasource/proto" "google.golang.org/protobuf/types/known/timestamppb" @@ -138,7 +138,7 @@ func TestWatcher_Process_ConfigApplySuccessfulTopic(t *testing.T) { response := &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", Timestamp: timestamppb.Now(), }, @@ -172,7 +172,7 @@ func TestWatcher_Process_RollbackCompleteTopic(t *testing.T) { response := &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", Timestamp: timestamppb.Now(), }, diff --git a/pkg/uuid/uuid.go b/pkg/uuid/uuid.go index 7dc0d09c6..7314dcf33 100644 --- a/pkg/uuid/uuid.go +++ b/pkg/uuid/uuid.go @@ -8,8 +8,6 @@ package uuid import ( "crypto/sha256" "fmt" - "log/slog" - "time" "github.com/google/uuid" ) @@ -50,13 +48,13 @@ func Generate(format string, a ...interface{}) string { // // Returns: // -// A string representation of the generated UUID. -func GenerateUUIDV7() string { +// A string representation of the generated UUID if successful. An empty string if unsuccessful +// An error +func GenerateUUIDV7() (string, error) { id, err := uuid.NewV7() if err != nil { - slog.Debug("issuing generating uuidv7, using sha256 and timestamp instead", "error", err) - return Generate("%s", time.Now().String()) + return "", err } - return id.String() + return id.String(), err } diff --git a/pkg/uuid/uuid_test.go b/pkg/uuid/uuid_test.go index 9a86921e6..7fb827439 100644 --- a/pkg/uuid/uuid_test.go +++ b/pkg/uuid/uuid_test.go @@ -8,7 +8,6 @@ package uuid import ( "testing" - "github.com/google/uuid" "github.com/stretchr/testify/assert" ) @@ -19,7 +18,6 @@ func TestGenerate(t *testing.T) { } func TestGenerateUUIDV7_Success(t *testing.T) { - result := GenerateUUIDV7() - _, err := uuid.Parse(result) + _, err := GenerateUUIDV7() assert.NoError(t, err, "Generated UUIDv7 should be valid") } diff --git a/test/helpers/os_utils.go b/test/helpers/os_utils.go index 6a9544223..5670bb02c 100644 --- a/test/helpers/os_utils.go +++ b/test/helpers/os_utils.go @@ -8,6 +8,7 @@ package helpers import ( "os" "regexp" + "strings" "testing" "github.com/stretchr/testify/require" @@ -15,6 +16,7 @@ import ( const ( filePermission = 0o700 + specialChars = "#$%\x00\x01\n" ) func CreateDirWithErrorCheck(t testing.TB, dirName string) { @@ -49,6 +51,7 @@ func RemoveASCIIControlSignals(t testing.TB, input string) string { // Use a regex to match and remove ASCII control characters (0x00 to 0x1F and 0x7F). // by matching all control characters (ASCII 0–31 and 127). re := regexp.MustCompile(`[[:cntrl:]]`) + output := strings.Trim(re.ReplaceAllString(input, ""), specialChars) - return re.ReplaceAllString(input, "") + return output } diff --git a/test/helpers/os_utils_test.go b/test/helpers/os_utils_test.go index d1c323702..b7d601580 100644 --- a/test/helpers/os_utils_test.go +++ b/test/helpers/os_utils_test.go @@ -45,6 +45,11 @@ func TestRemoveASCIIControlSignals(t *testing.T) { name: "Agent version example", input: " nginx-agent version v3.0.0-4a64a94", expected: "nginx-agent version v3.0.0-4a64a94", }, + { + name: "Agent version example alpine", + input: "#nginx-agent version v3.0.0-f94d93a", + expected: "nginx-agent version v3.0.0-f94d93a", + }, } for _, test := range tests { diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index 28ac75a53..ce9abd24e 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -22,8 +22,8 @@ import ( "github.com/gin-gonic/gin" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/internal/datasource/proto" "github.com/nginx/agent/v3/pkg/files" - "github.com/nginx/agent/v3/pkg/uuid" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/timestamppb" @@ -363,8 +363,8 @@ func (cs *CommandService) addConfigApplyEndpoint() { request := mpi.ManagementPlaneRequest{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), - CorrelationId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), + CorrelationId: proto.GenerateMessageID(), Timestamp: timestamppb.Now(), }, Request: &mpi.ManagementPlaneRequest_ConfigApplyRequest{ diff --git a/test/mock/grpc/mock_management_file_service.go b/test/mock/grpc/mock_management_file_service.go index 94f3a3d39..4a5485a41 100644 --- a/test/mock/grpc/mock_management_file_service.go +++ b/test/mock/grpc/mock_management_file_service.go @@ -14,7 +14,7 @@ import ( "strconv" "github.com/nginx/agent/v3/api/grpc/mpi/v1" - "github.com/nginx/agent/v3/pkg/uuid" + "github.com/nginx/agent/v3/internal/datasource/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" @@ -76,7 +76,7 @@ func (mgs *FileService) UpdateOverview( configUploadRequest := &v1.ManagementPlaneRequest{ MessageMeta: &v1.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), CorrelationId: request.GetMessageMeta().GetCorrelationId(), Timestamp: timestamppb.Now(), }, diff --git a/test/protos/data_plane_response.go b/test/protos/data_plane_response.go index d8c239698..5ce05c5c0 100644 --- a/test/protos/data_plane_response.go +++ b/test/protos/data_plane_response.go @@ -7,20 +7,22 @@ package protos import ( mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" - "github.com/nginx/agent/v3/pkg/uuid" + "github.com/nginx/agent/v3/internal/datasource/proto" "google.golang.org/protobuf/types/known/timestamppb" ) +const success = "Success" + func OKDataPlaneResponse() *mpi.DataPlaneResponse { return &mpi.DataPlaneResponse{ MessageMeta: &mpi.MessageMeta{ - MessageId: uuid.GenerateUUIDV7(), - CorrelationId: uuid.GenerateUUIDV7(), + MessageId: proto.GenerateMessageID(), + CorrelationId: proto.GenerateMessageID(), Timestamp: timestamppb.Now(), }, CommandResponse: &mpi.CommandResponse{ Status: mpi.CommandResponse_COMMAND_STATUS_OK, - Message: "Success", + Message: success, }, InstanceId: ossInstanceID, }