From dec099f645a47aacce020f3002186de02a060958 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Tue, 15 Oct 2024 16:37:03 +0100 Subject: [PATCH 01/12] refactor data plane response --- api/grpc/mpi/v1/command.pb.go | 686 ++++------------------ api/grpc/mpi/v1/common.pb.go | 48 +- api/grpc/mpi/v1/files.pb.go | 290 ++------- internal/file/file_plugin.go | 24 +- internal/file/file_plugin_test.go | 47 ++ internal/resource/resource_plugin.go | 12 +- internal/resource/resource_plugin_test.go | 20 +- internal/watcher/watcher_plugin.go | 18 +- internal/watcher/watcher_plugin_test.go | 41 +- 9 files changed, 316 insertions(+), 870 deletions(-) diff --git a/api/grpc/mpi/v1/command.pb.go b/api/grpc/mpi/v1/command.pb.go index 76ea4a02fd..7f6e52f857 100644 --- a/api/grpc/mpi/v1/command.pb.go +++ b/api/grpc/mpi/v1/command.pb.go @@ -8,7 +8,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc (unknown) // source: mpi/v1/command.proto @@ -162,11 +162,9 @@ type CreateConnectionRequest struct { func (x *CreateConnectionRequest) Reset() { *x = CreateConnectionRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreateConnectionRequest) String() string { @@ -177,7 +175,7 @@ func (*CreateConnectionRequest) ProtoMessage() {} func (x *CreateConnectionRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -227,11 +225,9 @@ type Resource struct { func (x *Resource) Reset() { *x = Resource{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Resource) String() string { @@ -242,7 +238,7 @@ func (*Resource) ProtoMessage() {} func (x *Resource) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -326,11 +322,9 @@ type HostInfo struct { func (x *HostInfo) Reset() { *x = HostInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HostInfo) String() string { @@ -341,7 +335,7 @@ func (*HostInfo) ProtoMessage() {} func (x *HostInfo) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -397,11 +391,9 @@ type ReleaseInfo struct { func (x *ReleaseInfo) Reset() { *x = ReleaseInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ReleaseInfo) String() string { @@ -412,7 +404,7 @@ func (*ReleaseInfo) ProtoMessage() {} func (x *ReleaseInfo) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -474,11 +466,9 @@ type ContainerInfo struct { func (x *ContainerInfo) Reset() { *x = ContainerInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ContainerInfo) String() string { @@ -489,7 +479,7 @@ func (*ContainerInfo) ProtoMessage() {} func (x *ContainerInfo) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -525,11 +515,9 @@ type CreateConnectionResponse struct { func (x *CreateConnectionResponse) Reset() { *x = CreateConnectionResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CreateConnectionResponse) String() string { @@ -540,7 +528,7 @@ func (*CreateConnectionResponse) ProtoMessage() {} func (x *CreateConnectionResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -583,11 +571,9 @@ type UpdateDataPlaneStatusRequest struct { func (x *UpdateDataPlaneStatusRequest) Reset() { *x = UpdateDataPlaneStatusRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateDataPlaneStatusRequest) String() string { @@ -598,7 +584,7 @@ func (*UpdateDataPlaneStatusRequest) ProtoMessage() {} func (x *UpdateDataPlaneStatusRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -636,11 +622,9 @@ type UpdateDataPlaneStatusResponse struct { func (x *UpdateDataPlaneStatusResponse) Reset() { *x = UpdateDataPlaneStatusResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateDataPlaneStatusResponse) String() string { @@ -651,7 +635,7 @@ func (*UpdateDataPlaneStatusResponse) ProtoMessage() {} func (x *UpdateDataPlaneStatusResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -680,11 +664,9 @@ type InstanceHealth struct { func (x *InstanceHealth) Reset() { *x = InstanceHealth{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *InstanceHealth) String() string { @@ -695,7 +677,7 @@ func (*InstanceHealth) ProtoMessage() {} func (x *InstanceHealth) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -745,11 +727,9 @@ type UpdateDataPlaneHealthRequest struct { func (x *UpdateDataPlaneHealthRequest) Reset() { *x = UpdateDataPlaneHealthRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateDataPlaneHealthRequest) String() string { @@ -760,7 +740,7 @@ func (*UpdateDataPlaneHealthRequest) ProtoMessage() {} func (x *UpdateDataPlaneHealthRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -798,11 +778,9 @@ type UpdateDataPlaneHealthResponse struct { func (x *UpdateDataPlaneHealthResponse) Reset() { *x = UpdateDataPlaneHealthResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateDataPlaneHealthResponse) String() string { @@ -813,7 +791,7 @@ func (*UpdateDataPlaneHealthResponse) ProtoMessage() {} func (x *UpdateDataPlaneHealthResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -844,11 +822,9 @@ type DataPlaneResponse struct { func (x *DataPlaneResponse) Reset() { *x = DataPlaneResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataPlaneResponse) String() string { @@ -859,7 +835,7 @@ func (*DataPlaneResponse) ProtoMessage() {} func (x *DataPlaneResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -916,11 +892,9 @@ type ManagementPlaneRequest struct { func (x *ManagementPlaneRequest) Reset() { *x = ManagementPlaneRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ManagementPlaneRequest) String() string { @@ -931,7 +905,7 @@ func (*ManagementPlaneRequest) ProtoMessage() {} func (x *ManagementPlaneRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1058,11 +1032,9 @@ type StatusRequest struct { func (x *StatusRequest) Reset() { *x = StatusRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StatusRequest) String() string { @@ -1073,7 +1045,7 @@ func (*StatusRequest) ProtoMessage() {} func (x *StatusRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1097,11 +1069,9 @@ type HealthRequest struct { func (x *HealthRequest) Reset() { *x = HealthRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HealthRequest) String() string { @@ -1112,7 +1082,7 @@ func (*HealthRequest) ProtoMessage() {} func (x *HealthRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1139,11 +1109,9 @@ type ConfigApplyRequest struct { func (x *ConfigApplyRequest) Reset() { *x = ConfigApplyRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ConfigApplyRequest) String() string { @@ -1154,7 +1122,7 @@ func (*ConfigApplyRequest) ProtoMessage() {} func (x *ConfigApplyRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1188,11 +1156,9 @@ type ConfigUploadRequest struct { func (x *ConfigUploadRequest) Reset() { *x = ConfigUploadRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ConfigUploadRequest) String() string { @@ -1203,7 +1169,7 @@ func (*ConfigUploadRequest) ProtoMessage() {} func (x *ConfigUploadRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1234,11 +1200,9 @@ type APIActionRequest struct { func (x *APIActionRequest) Reset() { *x = APIActionRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *APIActionRequest) String() string { @@ -1249,7 +1213,7 @@ func (*APIActionRequest) ProtoMessage() {} func (x *APIActionRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1273,11 +1237,9 @@ type CommandStatusRequest struct { func (x *CommandStatusRequest) Reset() { *x = CommandStatusRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CommandStatusRequest) String() string { @@ -1288,7 +1250,7 @@ func (*CommandStatusRequest) ProtoMessage() {} func (x *CommandStatusRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1319,11 +1281,9 @@ type Instance struct { func (x *Instance) Reset() { *x = Instance{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Instance) String() string { @@ -1334,7 +1294,7 @@ func (*Instance) ProtoMessage() {} func (x *Instance) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1386,11 +1346,9 @@ type InstanceMeta struct { func (x *InstanceMeta) Reset() { *x = InstanceMeta{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *InstanceMeta) String() string { @@ -1401,7 +1359,7 @@ func (*InstanceMeta) ProtoMessage() {} func (x *InstanceMeta) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1453,11 +1411,9 @@ type InstanceConfig struct { func (x *InstanceConfig) Reset() { *x = InstanceConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *InstanceConfig) String() string { @@ -1468,7 +1424,7 @@ func (*InstanceConfig) ProtoMessage() {} func (x *InstanceConfig) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1539,11 +1495,9 @@ type InstanceRuntime struct { func (x *InstanceRuntime) Reset() { *x = InstanceRuntime{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *InstanceRuntime) String() string { @@ -1554,7 +1508,7 @@ func (*InstanceRuntime) ProtoMessage() {} func (x *InstanceRuntime) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1647,11 +1601,9 @@ type InstanceChild struct { func (x *InstanceChild) Reset() { *x = InstanceChild{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *InstanceChild) String() string { @@ -1662,7 +1614,7 @@ func (*InstanceChild) ProtoMessage() {} func (x *InstanceChild) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1704,11 +1656,9 @@ type NGINXRuntimeInfo struct { func (x *NGINXRuntimeInfo) Reset() { *x = NGINXRuntimeInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NGINXRuntimeInfo) String() string { @@ -1719,7 +1669,7 @@ func (*NGINXRuntimeInfo) ProtoMessage() {} func (x *NGINXRuntimeInfo) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1791,11 +1741,9 @@ type NGINXPlusRuntimeInfo struct { func (x *NGINXPlusRuntimeInfo) Reset() { *x = NGINXPlusRuntimeInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NGINXPlusRuntimeInfo) String() string { @@ -1806,7 +1754,7 @@ func (*NGINXPlusRuntimeInfo) ProtoMessage() {} func (x *NGINXPlusRuntimeInfo) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1872,11 +1820,9 @@ type InstanceAction struct { func (x *InstanceAction) Reset() { *x = InstanceAction{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *InstanceAction) String() string { @@ -1887,7 +1833,7 @@ func (*InstanceAction) ProtoMessage() {} func (x *InstanceAction) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1924,11 +1870,9 @@ type AgentConfig struct { func (x *AgentConfig) Reset() { *x = AgentConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AgentConfig) String() string { @@ -1939,7 +1883,7 @@ func (*AgentConfig) ProtoMessage() {} func (x *AgentConfig) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2005,11 +1949,9 @@ type CommandServer struct { func (x *CommandServer) Reset() { *x = CommandServer{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CommandServer) String() string { @@ -2020,7 +1962,7 @@ func (*CommandServer) ProtoMessage() {} func (x *CommandServer) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2044,11 +1986,9 @@ type MetricsServer struct { func (x *MetricsServer) Reset() { *x = MetricsServer{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MetricsServer) String() string { @@ -2059,7 +1999,7 @@ func (*MetricsServer) ProtoMessage() {} func (x *MetricsServer) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2083,11 +2023,9 @@ type FileServer struct { func (x *FileServer) Reset() { *x = FileServer{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_command_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_command_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FileServer) String() string { @@ -2098,7 +2036,7 @@ func (*FileServer) ProtoMessage() {} func (x *FileServer) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_command_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2555,380 +2493,6 @@ func file_mpi_v1_command_proto_init() { } file_mpi_v1_common_proto_init() file_mpi_v1_files_proto_init() - if !protoimpl.UnsafeEnabled { - file_mpi_v1_command_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*CreateConnectionRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*Resource); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*HostInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*ReleaseInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*ContainerInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*CreateConnectionResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*UpdateDataPlaneStatusRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*UpdateDataPlaneStatusResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*InstanceHealth); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*UpdateDataPlaneHealthRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*UpdateDataPlaneHealthResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*DataPlaneResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*ManagementPlaneRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*StatusRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*HealthRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*ConfigApplyRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*ConfigUploadRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[17].Exporter = func(v any, i int) any { - switch v := v.(*APIActionRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[18].Exporter = func(v any, i int) any { - switch v := v.(*CommandStatusRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[19].Exporter = func(v any, i int) any { - switch v := v.(*Instance); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[20].Exporter = func(v any, i int) any { - switch v := v.(*InstanceMeta); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[21].Exporter = func(v any, i int) any { - switch v := v.(*InstanceConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[22].Exporter = func(v any, i int) any { - switch v := v.(*InstanceRuntime); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[23].Exporter = func(v any, i int) any { - switch v := v.(*InstanceChild); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[24].Exporter = func(v any, i int) any { - switch v := v.(*NGINXRuntimeInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[25].Exporter = func(v any, i int) any { - switch v := v.(*NGINXPlusRuntimeInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[26].Exporter = func(v any, i int) any { - switch v := v.(*InstanceAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[27].Exporter = func(v any, i int) any { - switch v := v.(*AgentConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[28].Exporter = func(v any, i int) any { - switch v := v.(*CommandServer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[29].Exporter = func(v any, i int) any { - switch v := v.(*MetricsServer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_command_proto_msgTypes[30].Exporter = func(v any, i int) any { - switch v := v.(*FileServer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } file_mpi_v1_command_proto_msgTypes[1].OneofWrappers = []any{ (*Resource_HostInfo)(nil), (*Resource_ContainerInfo)(nil), diff --git a/api/grpc/mpi/v1/common.pb.go b/api/grpc/mpi/v1/common.pb.go index ca47776c11..3d71214d35 100644 --- a/api/grpc/mpi/v1/common.pb.go +++ b/api/grpc/mpi/v1/common.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc (unknown) // source: mpi/v1/common.proto @@ -104,11 +104,9 @@ type MessageMeta struct { func (x *MessageMeta) Reset() { *x = MessageMeta{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_common_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MessageMeta) String() string { @@ -119,7 +117,7 @@ func (*MessageMeta) ProtoMessage() {} func (x *MessageMeta) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_common_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -171,11 +169,9 @@ type CommandResponse struct { func (x *CommandResponse) Reset() { *x = CommandResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_common_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CommandResponse) String() string { @@ -186,7 +182,7 @@ func (*CommandResponse) ProtoMessage() {} func (x *CommandResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_common_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -296,32 +292,6 @@ func file_mpi_v1_common_proto_init() { if File_mpi_v1_common_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_mpi_v1_common_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*MessageMeta); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_common_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*CommandResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/api/grpc/mpi/v1/files.pb.go b/api/grpc/mpi/v1/files.pb.go index a9d6743ecd..b02e2c6cf8 100644 --- a/api/grpc/mpi/v1/files.pb.go +++ b/api/grpc/mpi/v1/files.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc (unknown) // source: mpi/v1/files.proto @@ -102,11 +102,9 @@ type GetOverviewRequest struct { func (x *GetOverviewRequest) Reset() { *x = GetOverviewRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GetOverviewRequest) String() string { @@ -117,7 +115,7 @@ func (*GetOverviewRequest) ProtoMessage() {} func (x *GetOverviewRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -158,11 +156,9 @@ type GetOverviewResponse struct { func (x *GetOverviewResponse) Reset() { *x = GetOverviewResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GetOverviewResponse) String() string { @@ -173,7 +169,7 @@ func (*GetOverviewResponse) ProtoMessage() {} func (x *GetOverviewResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -209,11 +205,9 @@ type UpdateOverviewRequest struct { func (x *UpdateOverviewRequest) Reset() { *x = UpdateOverviewRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateOverviewRequest) String() string { @@ -224,7 +218,7 @@ func (*UpdateOverviewRequest) ProtoMessage() {} func (x *UpdateOverviewRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -262,11 +256,9 @@ type UpdateOverviewResponse struct { func (x *UpdateOverviewResponse) Reset() { *x = UpdateOverviewResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateOverviewResponse) String() string { @@ -277,7 +269,7 @@ func (*UpdateOverviewResponse) ProtoMessage() {} func (x *UpdateOverviewResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -306,11 +298,9 @@ type ConfigVersion struct { func (x *ConfigVersion) Reset() { *x = ConfigVersion{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ConfigVersion) String() string { @@ -321,7 +311,7 @@ func (*ConfigVersion) ProtoMessage() {} func (x *ConfigVersion) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -364,11 +354,9 @@ type FileOverview struct { func (x *FileOverview) Reset() { *x = FileOverview{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FileOverview) String() string { @@ -379,7 +367,7 @@ func (*FileOverview) ProtoMessage() {} func (x *FileOverview) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -422,11 +410,9 @@ type File struct { func (x *File) Reset() { *x = File{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *File) String() string { @@ -437,7 +423,7 @@ func (*File) ProtoMessage() {} func (x *File) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -480,11 +466,9 @@ type GetFileRequest struct { func (x *GetFileRequest) Reset() { *x = GetFileRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GetFileRequest) String() string { @@ -495,7 +479,7 @@ func (*GetFileRequest) ProtoMessage() {} func (x *GetFileRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -536,11 +520,9 @@ type GetFileResponse struct { func (x *GetFileResponse) Reset() { *x = GetFileResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GetFileResponse) String() string { @@ -551,7 +533,7 @@ func (*GetFileResponse) ProtoMessage() {} func (x *GetFileResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -585,11 +567,9 @@ type FileContents struct { func (x *FileContents) Reset() { *x = FileContents{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FileContents) String() string { @@ -600,7 +580,7 @@ func (*FileContents) ProtoMessage() {} func (x *FileContents) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -642,11 +622,9 @@ type FileMeta struct { func (x *FileMeta) Reset() { *x = FileMeta{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FileMeta) String() string { @@ -657,7 +635,7 @@ func (*FileMeta) ProtoMessage() {} func (x *FileMeta) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -723,11 +701,9 @@ type UpdateFileRequest struct { func (x *UpdateFileRequest) Reset() { *x = UpdateFileRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateFileRequest) String() string { @@ -738,7 +714,7 @@ func (*UpdateFileRequest) ProtoMessage() {} func (x *UpdateFileRequest) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -786,11 +762,9 @@ type UpdateFileResponse struct { func (x *UpdateFileResponse) Reset() { *x = UpdateFileResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_mpi_v1_files_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_mpi_v1_files_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UpdateFileResponse) String() string { @@ -801,7 +775,7 @@ func (*UpdateFileResponse) ProtoMessage() {} func (x *UpdateFileResponse) ProtoReflect() protoreflect.Message { mi := &file_mpi_v1_files_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1021,164 +995,6 @@ func file_mpi_v1_files_proto_init() { return } file_mpi_v1_common_proto_init() - if !protoimpl.UnsafeEnabled { - file_mpi_v1_files_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*GetOverviewRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*GetOverviewResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*UpdateOverviewRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*UpdateOverviewResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*ConfigVersion); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*FileOverview); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*File); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*GetFileRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*GetFileResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*FileContents); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*FileMeta); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*UpdateFileRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_mpi_v1_files_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*UpdateFileResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } file_mpi_v1_files_proto_msgTypes[6].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ diff --git a/internal/file/file_plugin.go b/internal/file/file_plugin.go index 4e83a0acbf..48e167b6ab 100644 --- a/internal/file/file_plugin.go +++ b/internal/file/file_plugin.go @@ -69,7 +69,7 @@ func (fp *FilePlugin) Process(ctx context.Context, msg *bus.Message) { case bus.ConfigApplyRequestTopic: fp.handleConfigApplyRequest(ctx, msg) case bus.ConfigApplySuccessfulTopic, bus.RollbackCompleteTopic: - fp.clearCache() + fp.handleConfigApplyRollbackComplete(ctx, msg) case bus.ConfigApplyFailedTopic: fp.handleConfigApplyFailedRequest(ctx, msg) default: @@ -89,9 +89,17 @@ func (fp *FilePlugin) Subscriptions() []string { } } -func (fp *FilePlugin) clearCache() { - slog.Debug("Clearing cache after config apply") +func (fp *FilePlugin) handleConfigApplyRollbackComplete(ctx context.Context, msg *bus.Message) { + response, ok := msg.Data.(*mpi.DataPlaneResponse) + + if !ok { + slog.ErrorContext(ctx, "Unable to cast message payload to *mpi.DataPlaneResponse", "payload", msg.Data) + return + } + + slog.Info("Data Plane Response", "data", response) fp.fileManagerService.ClearCache() + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) } func (fp *FilePlugin) handleConfigApplyFailedRequest(ctx context.Context, msg *bus.Message) { @@ -114,9 +122,9 @@ func (fp *FilePlugin) handleConfigApplyFailedRequest(ctx context.Context, msg *b mpi.CommandResponse_COMMAND_STATUS_FAILURE, "Config apply failed, rollback failed", data.InstanceID, data.Error.Error()) + fp.fileManagerService.ClearCache() fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: rollbackResponse}) fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: applyResponse}) - fp.fileManagerService.ClearCache() return } @@ -160,9 +168,9 @@ func (fp *FilePlugin) handleConfigApplyRequest(ctx context.Context, msg *bus.Mes "", ) + fp.fileManagerService.ClearCache() fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplySuccessfulTopic, Data: instanceID}) - fp.fileManagerService.ClearCache() return case model.Error: @@ -180,8 +188,8 @@ func (fp *FilePlugin) handleConfigApplyRequest(ctx context.Context, msg *bus.Mes err.Error(), ) - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) fp.fileManagerService.ClearCache() + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) return case model.RollbackRequired: @@ -212,8 +220,8 @@ func (fp *FilePlugin) handleConfigApplyRequest(ctx context.Context, msg *bus.Mes "Config apply failed, rollback failed", configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), rollbackErr.Error()) - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: rollbackResponse}) fp.fileManagerService.ClearCache() + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: rollbackResponse}) return } @@ -224,8 +232,8 @@ func (fp *FilePlugin) handleConfigApplyRequest(ctx context.Context, msg *bus.Mes "Config apply failed, rollback successful", configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), err.Error()) - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) fp.fileManagerService.ClearCache() + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) return case model.OK: diff --git a/internal/file/file_plugin_test.go b/internal/file/file_plugin_test.go index e1ca4b3d55..86fb4933c0 100644 --- a/internal/file/file_plugin_test.go +++ b/internal/file/file_plugin_test.go @@ -12,6 +12,9 @@ import ( "testing" "time" + "github.com/google/uuid" + "google.golang.org/protobuf/types/known/timestamppb" + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/api/grpc/mpi/v1/v1fakes" "github.com/nginx/agent/v3/internal/bus" @@ -426,3 +429,47 @@ func TestFilePlugin_Process_ConfigApplyFailedTopic(t *testing.T) { }) } } + +func TestFilePlugin_Process_ConfigApllyRollbackCompleteTopic(t *testing.T) { + ctx := context.Background() + instance := protos.GetNginxOssInstance([]string{}) + mockFileManager := &filefakes.FakeFileManagerServiceInterface{} + + messagePipe := bus.NewFakeMessagePipe() + agentConfig := types.AgentConfig() + fakeGrpcConnection := &grpcfakes.FakeGrpcConnectionInterface{} + filePlugin := NewFilePlugin(agentConfig, fakeGrpcConnection) + + err := filePlugin.Init(ctx, messagePipe) + require.NoError(t, err) + filePlugin.fileManagerService = mockFileManager + + expectedResponse := &mpi.DataPlaneResponse{ + MessageMeta: &mpi.MessageMeta{ + MessageId: uuid.NewString(), + CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", + Timestamp: timestamppb.Now(), + }, + CommandResponse: &mpi.CommandResponse{ + Status: mpi.CommandResponse_COMMAND_STATUS_OK, + Message: "Config apply successful", + Error: "", + }, + InstanceId: instance.GetInstanceMeta().GetInstanceId(), + } + + filePlugin.Process(ctx, &bus.Message{Topic: bus.ConfigApplySuccessfulTopic, Data: expectedResponse}) + + messages := messagePipe.GetMessages() + response, ok := messages[0].Data.(*mpi.DataPlaneResponse) + assert.True(t, ok) + + assert.Equal(t, expectedResponse.GetCommandResponse().GetStatus(), response.GetCommandResponse().GetStatus()) + assert.Equal(t, expectedResponse.GetCommandResponse().GetMessage(), response.GetCommandResponse().GetMessage()) + assert.Equal(t, expectedResponse.GetCommandResponse().GetError(), response.GetCommandResponse().GetError()) + assert.Equal(t, expectedResponse.GetMessageMeta().GetCorrelationId(), response.GetMessageMeta().GetCorrelationId()) + + assert.Equal(t, expectedResponse.GetInstanceId(), response.GetInstanceId()) + + t.Logf("Messages: %v", messages) +} diff --git a/internal/resource/resource_plugin.go b/internal/resource/resource_plugin.go index a5779aa2f3..f916761f93 100644 --- a/internal/resource/resource_plugin.go +++ b/internal/resource/resource_plugin.go @@ -137,17 +137,15 @@ func (r *Resource) handleWriteConfigSuccessful(ctx context.Context, msg *bus.Mes return } + response := r.createDataPlaneResponse(data.CorrelationID, mpi.CommandResponse_COMMAND_STATUS_OK, "Config apply successful", data.InstanceID, "") - instance := r.resourceService.Instance(data.InstanceID) - - r.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) r.messagePipe.Process( ctx, &bus.Message{ Topic: bus.ConfigApplySuccessfulTopic, - Data: instance.GetInstanceMeta().GetInstanceId(), + Data: response, }, ) } @@ -170,9 +168,8 @@ func (r *Resource) handleRollbackWrite(ctx context.Context, msg *bus.Message) { mpi.CommandResponse_COMMAND_STATUS_FAILURE, "Config apply failed, rollback failed", data.InstanceID, data.Error.Error()) - r.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: applyResponse}) r.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: rollbackResponse}) - r.messagePipe.Process(ctx, &bus.Message{Topic: bus.RollbackCompleteTopic, Data: data.InstanceID}) + r.messagePipe.Process(ctx, &bus.Message{Topic: bus.RollbackCompleteTopic, Data: applyResponse}) return } @@ -181,8 +178,7 @@ func (r *Resource) handleRollbackWrite(ctx context.Context, msg *bus.Message) { mpi.CommandResponse_COMMAND_STATUS_FAILURE, "Config apply failed, rollback successful", data.InstanceID, data.Error.Error()) - r.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: applyResponse}) - r.messagePipe.Process(ctx, &bus.Message{Topic: bus.RollbackCompleteTopic, Data: data.InstanceID}) + r.messagePipe.Process(ctx, &bus.Message{Topic: bus.RollbackCompleteTopic, Data: applyResponse}) } func (*Resource) createDataPlaneResponse(correlationID string, status mpi.CommandResponse_CommandStatus, diff --git a/internal/resource/resource_plugin_test.go b/internal/resource/resource_plugin_test.go index cebeb61b3b..49f1bb0425 100644 --- a/internal/resource/resource_plugin_test.go +++ b/internal/resource/resource_plugin_test.go @@ -133,7 +133,7 @@ func TestResource_Process_Apply(t *testing.T) { }, }, applyErr: nil, - topic: []string{bus.DataPlaneResponseTopic, bus.ConfigApplySuccessfulTopic}, + topic: []string{bus.ConfigApplySuccessfulTopic}, }, { name: "Test 2: Write Config Successful Topic - Fail Status", @@ -167,7 +167,10 @@ func TestResource_Process_Apply(t *testing.T) { resourcePlugin.Process(ctx, test.message) assert.Equal(t, test.topic[0], messagePipe.GetMessages()[0].Topic) - assert.Equal(t, test.topic[1], messagePipe.GetMessages()[1].Topic) + + if len(test.topic) > 1 { + assert.Equal(t, test.topic[1], messagePipe.GetMessages()[1].Topic) + } if test.applyErr != nil { response, ok := messagePipe.GetMessages()[0].Data.(*mpi.DataPlaneResponse) @@ -198,7 +201,7 @@ func TestResource_Process_Rollback(t *testing.T) { }, }, rollbackErr: nil, - topic: []string{bus.RollbackCompleteTopic, bus.DataPlaneResponseTopic}, + topic: []string{bus.RollbackCompleteTopic}, }, { name: "Test 2: Rollback Write Topic - Fail Status", @@ -211,7 +214,7 @@ func TestResource_Process_Rollback(t *testing.T) { }, }, rollbackErr: errors.New("error reloading"), - topic: []string{bus.RollbackCompleteTopic, bus.DataPlaneResponseTopic, bus.DataPlaneResponseTopic}, + topic: []string{bus.RollbackCompleteTopic, bus.DataPlaneResponseTopic}, }, } @@ -238,12 +241,15 @@ func TestResource_Process_Rollback(t *testing.T) { assert.Equal(tt, len(test.topic), len(messagePipe.GetMessages())) assert.Equal(t, test.topic[0], messagePipe.GetMessages()[0].Topic) - assert.Equal(t, test.topic[1], messagePipe.GetMessages()[1].Topic) + + if len(test.topic) > 1 { + assert.Equal(t, test.topic[1], messagePipe.GetMessages()[1].Topic) + } if test.rollbackErr != nil { - rollbackResponse, ok := messagePipe.GetMessages()[2].Data.(*mpi.DataPlaneResponse) + rollbackResponse, ok := messagePipe.GetMessages()[1].Data.(*mpi.DataPlaneResponse) assert.True(tt, ok) - assert.Equal(t, test.topic[2], messagePipe.GetMessages()[2].Topic) + assert.Equal(t, test.topic[1], messagePipe.GetMessages()[1].Topic) assert.Equal(tt, test.rollbackErr.Error(), rollbackResponse.GetCommandResponse().GetError()) } }) diff --git a/internal/watcher/watcher_plugin.go b/internal/watcher/watcher_plugin.go index 255df0b115..f062d736ae 100644 --- a/internal/watcher/watcher_plugin.go +++ b/internal/watcher/watcher_plugin.go @@ -150,32 +150,38 @@ func (w *Watcher) handleConfigApplyRequest(ctx context.Context, msg *bus.Message } func (w *Watcher) handleConfigApplySuccess(ctx context.Context, msg *bus.Message) { - data, ok := msg.Data.(string) + response, ok := msg.Data.(*mpi.DataPlaneResponse) if !ok { - slog.ErrorContext(ctx, "Unable to cast message payload to string", "payload", msg.Data, "topic", msg.Topic) + slog.ErrorContext(ctx, "Unable to cast message payload to *mpi.DataPlaneResponse", "payload", + msg.Data, "topic", msg.Topic) return } + instanceID := response.GetInstanceId() + w.instancesWithConfigApplyInProgress = slices.DeleteFunc( w.instancesWithConfigApplyInProgress, func(element string) bool { - return element == data + return element == instanceID }, ) w.fileWatcherService.SetEnabled(true) - w.instanceWatcherService.ReparseConfig(ctx, data) + w.instanceWatcherService.ReparseConfig(ctx, instanceID) } func (w *Watcher) handleRollbackComplete(ctx context.Context, msg *bus.Message) { - instanceID, ok := msg.Data.(string) + response, ok := msg.Data.(*mpi.DataPlaneResponse) if !ok { - slog.ErrorContext(ctx, "Unable to cast message payload to string", "payload", msg.Data, "topic", msg.Topic) + slog.ErrorContext(ctx, "Unable to cast message payload to *mpi.DataPlaneResponse", "payload", + msg.Data, "topic", msg.Topic) return } + instanceID := response.GetInstanceId() + w.instancesWithConfigApplyInProgress = slices.DeleteFunc( w.instancesWithConfigApplyInProgress, func(element string) bool { diff --git a/internal/watcher/watcher_plugin_test.go b/internal/watcher/watcher_plugin_test.go index 28dcc59616..d7c6830975 100644 --- a/internal/watcher/watcher_plugin_test.go +++ b/internal/watcher/watcher_plugin_test.go @@ -10,6 +10,9 @@ import ( "testing" "time" + "github.com/google/uuid" + "google.golang.org/protobuf/types/known/timestamppb" + "github.com/nginx/agent/v3/internal/watcher/health" "github.com/nginx/agent/v3/internal/watcher/instance" "github.com/nginx/agent/v3/internal/watcher/watcherfakes" @@ -130,9 +133,24 @@ func TestWatcher_Process_ConfigApplyRequestTopic(t *testing.T) { func TestWatcher_Process_ConfigApplySuccessfulTopic(t *testing.T) { ctx := context.Background() data := protos.GetNginxOssInstance([]string{}) + + response := &mpi.DataPlaneResponse{ + MessageMeta: &mpi.MessageMeta{ + MessageId: uuid.NewString(), + CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", + Timestamp: timestamppb.Now(), + }, + CommandResponse: &mpi.CommandResponse{ + Status: mpi.CommandResponse_COMMAND_STATUS_OK, + Message: "Config apply successful", + Error: "", + }, + InstanceId: data.GetInstanceMeta().GetInstanceId(), + } + message := &bus.Message{ Topic: bus.ConfigApplySuccessfulTopic, - Data: data.GetInstanceMeta().GetInstanceId(), + Data: response, } fakeWatcherService := &watcherfakes.FakeInstanceWatcherServiceInterface{} @@ -148,14 +166,29 @@ func TestWatcher_Process_ConfigApplySuccessfulTopic(t *testing.T) { func TestWatcher_Process_RollbackCompleteTopic(t *testing.T) { ctx := context.Background() - instanceID := "123" + ossInstance := protos.GetNginxOssInstance([]string{}) + + response := &mpi.DataPlaneResponse{ + MessageMeta: &mpi.MessageMeta{ + MessageId: uuid.NewString(), + CorrelationId: "dfsbhj6-bc92-30c1-a9c9-85591422068e", + Timestamp: timestamppb.Now(), + }, + CommandResponse: &mpi.CommandResponse{ + Status: mpi.CommandResponse_COMMAND_STATUS_OK, + Message: "Config apply successful", + Error: "", + }, + InstanceId: ossInstance.GetInstanceMeta().GetInstanceId(), + } + message := &bus.Message{ Topic: bus.RollbackCompleteTopic, - Data: instanceID, + Data: response, } watcherPlugin := NewWatcher(types.AgentConfig()) - watcherPlugin.instancesWithConfigApplyInProgress = []string{instanceID} + watcherPlugin.instancesWithConfigApplyInProgress = []string{ossInstance.GetInstanceMeta().GetInstanceId()} watcherPlugin.Process(ctx, message) From 27bd739f79baa8c80f540dcbcdd057cebc0a7683 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Tue, 15 Oct 2024 16:50:59 +0100 Subject: [PATCH 02/12] clean up --- internal/file/file_plugin.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/file/file_plugin.go b/internal/file/file_plugin.go index 48e167b6ab..af522ca749 100644 --- a/internal/file/file_plugin.go +++ b/internal/file/file_plugin.go @@ -96,8 +96,7 @@ func (fp *FilePlugin) handleConfigApplyRollbackComplete(ctx context.Context, msg slog.ErrorContext(ctx, "Unable to cast message payload to *mpi.DataPlaneResponse", "payload", msg.Data) return } - - slog.Info("Data Plane Response", "data", response) + fp.fileManagerService.ClearCache() fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) } From 781984831b8f1b3c3e9a93860ec04de3ac8560e9 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Tue, 15 Oct 2024 16:53:30 +0100 Subject: [PATCH 03/12] clean up --- internal/file/file_plugin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/file/file_plugin.go b/internal/file/file_plugin.go index af522ca749..7aa962677b 100644 --- a/internal/file/file_plugin.go +++ b/internal/file/file_plugin.go @@ -96,7 +96,7 @@ func (fp *FilePlugin) handleConfigApplyRollbackComplete(ctx context.Context, msg slog.ErrorContext(ctx, "Unable to cast message payload to *mpi.DataPlaneResponse", "payload", msg.Data) return } - + fp.fileManagerService.ClearCache() fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) } From c8501fa44220bdc271e7587b6325bca1e2ce793e Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Thu, 24 Oct 2024 15:27:17 +0100 Subject: [PATCH 04/12] start of config apply refactor --- internal/bus/topics.go | 2 +- .../generated_component_test.go | 12 +- .../internal/metadata/generated_metrics.go | 54 ++--- .../metadata/generated_metrics_test.go | 18 +- .../generated_component_test.go | 12 +- .../internal/metadata/generated_metrics.go | 54 ++--- .../metadata/generated_metrics_test.go | 76 +++---- internal/file/file_manager_service.go | 130 ++++++++++-- internal/file/file_manager_service_test.go | 188 +++++++++++++++-- internal/file/file_plugin.go | 44 ++-- internal/file/file_plugin_test.go | 22 +- .../fake_file_manager_service_interface.go | 125 +++++++++++ internal/resource/resource_plugin.go | 4 +- internal/resource/resource_plugin_test.go | 6 +- internal/watcher/watcher_plugin.go | 4 +- internal/watcher/watcher_plugin_test.go | 4 +- pkg/files/file_helpers.go | 108 +--------- pkg/files/file_helpers_test.go | 194 ------------------ .../grpc_management_plane_api_test.go | 89 ++++---- .../grpc/mock_management_command_service.go | 11 +- test/protos/files.go | 3 +- 21 files changed, 615 insertions(+), 545 deletions(-) diff --git a/internal/bus/topics.go b/internal/bus/topics.go index 8099189b51..17386e6841 100644 --- a/internal/bus/topics.go +++ b/internal/bus/topics.go @@ -19,6 +19,6 @@ const ( WriteConfigSuccessfulTopic = "write-config-successful" ConfigApplySuccessfulTopic = "config-apply-successful" ConfigApplyFailedTopic = "config-apply-failed" - RollbackCompleteTopic = "rollback-complete" + ConfigApplyCompleteTopic = "config-apply-complete" RollbackWriteTopic = "rollback-write" ) diff --git a/internal/collector/nginxossreceiver/generated_component_test.go b/internal/collector/nginxossreceiver/generated_component_test.go index 60de562050..3007dc92b4 100644 --- a/internal/collector/nginxossreceiver/generated_component_test.go +++ b/internal/collector/nginxossreceiver/generated_component_test.go @@ -46,21 +46,21 @@ func TestComponentLifecycle(t *testing.T) { require.NoError(t, err) require.NoError(t, sub.Unmarshal(&cfg)) - for _, tt := range tests { - t.Run(tt.name+"-shutdown", func(t *testing.T) { - c, err := tt.createFn(context.Background(), receivertest.NewNopSettings(), cfg) + for _, test := range tests { + t.Run(test.name+"-shutdown", func(t *testing.T) { + c, err := test.createFn(context.Background(), receivertest.NewNopSettings(), cfg) require.NoError(t, err) err = c.Shutdown(context.Background()) require.NoError(t, err) }) - t.Run(tt.name+"-lifecycle", func(t *testing.T) { - firstRcvr, err := tt.createFn(context.Background(), receivertest.NewNopSettings(), cfg) + t.Run(test.name+"-lifecycle", func(t *testing.T) { + firstRcvr, err := test.createFn(context.Background(), receivertest.NewNopSettings(), cfg) require.NoError(t, err) host := componenttest.NewNopHost() require.NoError(t, err) require.NoError(t, firstRcvr.Start(context.Background(), host)) require.NoError(t, firstRcvr.Shutdown(context.Background())) - secondRcvr, err := tt.createFn(context.Background(), receivertest.NewNopSettings(), cfg) + secondRcvr, err := test.createFn(context.Background(), receivertest.NewNopSettings(), cfg) require.NoError(t, err) require.NoError(t, secondRcvr.Start(context.Background(), host)) require.NoError(t, secondRcvr.Shutdown(context.Background())) diff --git a/internal/collector/nginxossreceiver/internal/metadata/generated_metrics.go b/internal/collector/nginxossreceiver/internal/metadata/generated_metrics.go index c560fe1bc8..e74642bc94 100644 --- a/internal/collector/nginxossreceiver/internal/metadata/generated_metrics.go +++ b/internal/collector/nginxossreceiver/internal/metadata/generated_metrics.go @@ -313,25 +313,17 @@ type MetricsBuilder struct { metricNginxHTTPResponseStatus metricNginxHTTPResponseStatus } -// MetricBuilderOption applies changes to default metrics builder. -type MetricBuilderOption interface { - apply(*MetricsBuilder) -} - -type metricBuilderOptionFunc func(mb *MetricsBuilder) - -func (mbof metricBuilderOptionFunc) apply(mb *MetricsBuilder) { - mbof(mb) -} +// metricBuilderOption applies changes to default metrics builder. +type metricBuilderOption func(*MetricsBuilder) // WithStartTime sets startTime on the metrics builder. -func WithStartTime(startTime pcommon.Timestamp) MetricBuilderOption { - return metricBuilderOptionFunc(func(mb *MetricsBuilder) { +func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { + return func(mb *MetricsBuilder) { mb.startTime = startTime - }) + } } -func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, options ...MetricBuilderOption) *MetricsBuilder { +func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, options ...metricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ config: mbc, startTime: pcommon.NewTimestampFromTime(time.Now()), @@ -344,7 +336,7 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt } for _, op := range options { - op.apply(mb) + op(mb) } return mb } @@ -357,28 +349,20 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption interface { - apply(pmetric.ResourceMetrics) -} - -type resourceMetricsOptionFunc func(pmetric.ResourceMetrics) - -func (rmof resourceMetricsOptionFunc) apply(rm pmetric.ResourceMetrics) { - rmof(rm) -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) // WithResource sets the provided resource on the emitted ResourceMetrics. // It's recommended to use ResourceBuilder to create the resource. func WithResource(res pcommon.Resource) ResourceMetricsOption { - return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { res.CopyTo(rm.Resource()) - }) + } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -392,7 +376,7 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { dps.At(j).SetStartTimestamp(start) } } - }) + } } // EmitForResource saves all the generated metrics under a new resource and updates the internal state to be ready for @@ -400,7 +384,7 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // needs to emit metrics from several resources. Otherwise calling this function is not required, // just `Emit` function can be called instead. // Resource attributes should be provided as ResourceMetricsOption arguments. -func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { +func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/nginxreceiver") @@ -411,8 +395,8 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricNginxHTTPRequests.emit(ils.Metrics()) mb.metricNginxHTTPResponseStatus.emit(ils.Metrics()) - for _, op := range options { - op.apply(rm) + for _, op := range rmo { + op(rm) } if ils.Metrics().Len() > 0 { @@ -424,8 +408,8 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { // Emit returns all the metrics accumulated by the metrics builder and updates the internal state to be ready for // recording another set of metrics. This function will be responsible for applying all the transformations required to // produce metric representation defined in metadata and user config, e.g. delta or cumulative. -func (mb *MetricsBuilder) Emit(options ...ResourceMetricsOption) pmetric.Metrics { - mb.EmitForResource(options...) +func (mb *MetricsBuilder) Emit(rmo ...ResourceMetricsOption) pmetric.Metrics { + mb.EmitForResource(rmo...) metrics := mb.metricsBuffer mb.metricsBuffer = pmetric.NewMetrics() return metrics @@ -453,9 +437,9 @@ func (mb *MetricsBuilder) RecordNginxHTTPResponseStatusDataPoint(ts pcommon.Time // Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, // and metrics builder should update its startTime and reset it's internal state accordingly. -func (mb *MetricsBuilder) Reset(options ...MetricBuilderOption) { +func (mb *MetricsBuilder) Reset(options ...metricBuilderOption) { mb.startTime = pcommon.NewTimestampFromTime(time.Now()) for _, op := range options { - op.apply(mb) + op(mb) } } diff --git a/internal/collector/nginxossreceiver/internal/metadata/generated_metrics_test.go b/internal/collector/nginxossreceiver/internal/metadata/generated_metrics_test.go index 2581a33ef3..261655b70a 100644 --- a/internal/collector/nginxossreceiver/internal/metadata/generated_metrics_test.go +++ b/internal/collector/nginxossreceiver/internal/metadata/generated_metrics_test.go @@ -43,14 +43,14 @@ func TestMetricsBuilder(t *testing.T) { expectEmpty: true, }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { start := pcommon.Timestamp(1_000_000_000) ts := pcommon.Timestamp(1_000_001_000) observedZapCore, observedLogs := observer.New(zap.WarnLevel) settings := receivertest.NewNopSettings() settings.Logger = zap.New(observedZapCore) - mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, tt.name), settings, WithStartTime(start)) + mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, test.name), settings, WithStartTime(start)) expectedWarnings := 0 @@ -78,7 +78,7 @@ func TestMetricsBuilder(t *testing.T) { res := pcommon.NewResource() metrics := mb.Emit(WithResource(res)) - if tt.expectEmpty { + if test.expectEmpty { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) return } @@ -88,10 +88,10 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() - if tt.metricsSet == testDataSetDefault { + if test.metricsSet == testDataSetDefault { assert.Equal(t, defaultMetricsCount, ms.Len()) } - if tt.metricsSet == testDataSetAll { + if test.metricsSet == testDataSetAll { assert.Equal(t, allMetricsCount, ms.Len()) } validatedMetrics := make(map[string]bool) @@ -104,7 +104,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of connections.", ms.At(i).Description()) assert.Equal(t, "connections", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -136,7 +136,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of client requests received from clients.", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -150,7 +150,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The number of responses, grouped by status code range.", ms.At(i).Description()) assert.Equal(t, "responses", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) diff --git a/internal/collector/nginxplusreceiver/generated_component_test.go b/internal/collector/nginxplusreceiver/generated_component_test.go index 9fbb9944ca..170385ba71 100644 --- a/internal/collector/nginxplusreceiver/generated_component_test.go +++ b/internal/collector/nginxplusreceiver/generated_component_test.go @@ -46,21 +46,21 @@ func TestComponentLifecycle(t *testing.T) { require.NoError(t, err) require.NoError(t, sub.Unmarshal(&cfg)) - for _, tt := range tests { - t.Run(tt.name+"-shutdown", func(t *testing.T) { - c, err := tt.createFn(context.Background(), receivertest.NewNopSettings(), cfg) + for _, test := range tests { + t.Run(test.name+"-shutdown", func(t *testing.T) { + c, err := test.createFn(context.Background(), receivertest.NewNopSettings(), cfg) require.NoError(t, err) err = c.Shutdown(context.Background()) require.NoError(t, err) }) - t.Run(tt.name+"-lifecycle", func(t *testing.T) { - firstRcvr, err := tt.createFn(context.Background(), receivertest.NewNopSettings(), cfg) + t.Run(test.name+"-lifecycle", func(t *testing.T) { + firstRcvr, err := test.createFn(context.Background(), receivertest.NewNopSettings(), cfg) require.NoError(t, err) host := componenttest.NewNopHost() require.NoError(t, err) require.NoError(t, firstRcvr.Start(context.Background(), host)) require.NoError(t, firstRcvr.Shutdown(context.Background())) - secondRcvr, err := tt.createFn(context.Background(), receivertest.NewNopSettings(), cfg) + secondRcvr, err := test.createFn(context.Background(), receivertest.NewNopSettings(), cfg) require.NoError(t, err) require.NoError(t, secondRcvr.Start(context.Background(), host)) require.NoError(t, secondRcvr.Shutdown(context.Background())) diff --git a/internal/collector/nginxplusreceiver/internal/metadata/generated_metrics.go b/internal/collector/nginxplusreceiver/internal/metadata/generated_metrics.go index 15dbba1752..866fb5a735 100644 --- a/internal/collector/nginxplusreceiver/internal/metadata/generated_metrics.go +++ b/internal/collector/nginxplusreceiver/internal/metadata/generated_metrics.go @@ -3620,25 +3620,17 @@ type MetricsBuilder struct { metricNginxStreamUpstreamZombieCount metricNginxStreamUpstreamZombieCount } -// MetricBuilderOption applies changes to default metrics builder. -type MetricBuilderOption interface { - apply(*MetricsBuilder) -} - -type metricBuilderOptionFunc func(mb *MetricsBuilder) - -func (mbof metricBuilderOptionFunc) apply(mb *MetricsBuilder) { - mbof(mb) -} +// metricBuilderOption applies changes to default metrics builder. +type metricBuilderOption func(*MetricsBuilder) // WithStartTime sets startTime on the metrics builder. -func WithStartTime(startTime pcommon.Timestamp) MetricBuilderOption { - return metricBuilderOptionFunc(func(mb *MetricsBuilder) { +func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { + return func(mb *MetricsBuilder) { mb.startTime = startTime - }) + } } -func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, options ...MetricBuilderOption) *MetricsBuilder { +func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, options ...metricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ config: mbc, startTime: pcommon.NewTimestampFromTime(time.Now()), @@ -3705,7 +3697,7 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt } for _, op := range options { - op.apply(mb) + op(mb) } return mb } @@ -3718,28 +3710,20 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption interface { - apply(pmetric.ResourceMetrics) -} - -type resourceMetricsOptionFunc func(pmetric.ResourceMetrics) - -func (rmof resourceMetricsOptionFunc) apply(rm pmetric.ResourceMetrics) { - rmof(rm) -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) // WithResource sets the provided resource on the emitted ResourceMetrics. // It's recommended to use ResourceBuilder to create the resource. func WithResource(res pcommon.Resource) ResourceMetricsOption { - return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { res.CopyTo(rm.Resource()) - }) + } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -3753,7 +3737,7 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { dps.At(j).SetStartTimestamp(start) } } - }) + } } // EmitForResource saves all the generated metrics under a new resource and updates the internal state to be ready for @@ -3761,7 +3745,7 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // needs to emit metrics from several resources. Otherwise calling this function is not required, // just `Emit` function can be called instead. // Resource attributes should be provided as ResourceMetricsOption arguments. -func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { +func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/nginxplusreceiver") @@ -3826,8 +3810,8 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricNginxStreamUpstreamPeerUnavailable.emit(ils.Metrics()) mb.metricNginxStreamUpstreamZombieCount.emit(ils.Metrics()) - for _, op := range options { - op.apply(rm) + for _, op := range rmo { + op(rm) } if ils.Metrics().Len() > 0 { @@ -3839,8 +3823,8 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { // Emit returns all the metrics accumulated by the metrics builder and updates the internal state to be ready for // recording another set of metrics. This function will be responsible for applying all the transformations required to // produce metric representation defined in metadata and user config, e.g. delta or cumulative. -func (mb *MetricsBuilder) Emit(options ...ResourceMetricsOption) pmetric.Metrics { - mb.EmitForResource(options...) +func (mb *MetricsBuilder) Emit(rmo ...ResourceMetricsOption) pmetric.Metrics { + mb.EmitForResource(rmo...) metrics := mb.metricsBuffer mb.metricsBuffer = pmetric.NewMetrics() return metrics @@ -4138,9 +4122,9 @@ func (mb *MetricsBuilder) RecordNginxStreamUpstreamZombieCountDataPoint(ts pcomm // Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, // and metrics builder should update its startTime and reset it's internal state accordingly. -func (mb *MetricsBuilder) Reset(options ...MetricBuilderOption) { +func (mb *MetricsBuilder) Reset(options ...metricBuilderOption) { mb.startTime = pcommon.NewTimestampFromTime(time.Now()) for _, op := range options { - op.apply(mb) + op(mb) } } diff --git a/internal/collector/nginxplusreceiver/internal/metadata/generated_metrics_test.go b/internal/collector/nginxplusreceiver/internal/metadata/generated_metrics_test.go index 6d048f6442..8e8f64cbb9 100644 --- a/internal/collector/nginxplusreceiver/internal/metadata/generated_metrics_test.go +++ b/internal/collector/nginxplusreceiver/internal/metadata/generated_metrics_test.go @@ -43,14 +43,14 @@ func TestMetricsBuilder(t *testing.T) { expectEmpty: true, }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { start := pcommon.Timestamp(1_000_000_000) ts := pcommon.Timestamp(1_000_001_000) observedZapCore, observedLogs := observer.New(zap.WarnLevel) settings := receivertest.NewNopSettings() settings.Logger = zap.New(observedZapCore) - mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, tt.name), settings, WithStartTime(start)) + mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, test.name), settings, WithStartTime(start)) expectedWarnings := 0 @@ -294,7 +294,7 @@ func TestMetricsBuilder(t *testing.T) { res := pcommon.NewResource() metrics := mb.Emit(WithResource(res)) - if tt.expectEmpty { + if test.expectEmpty { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) return } @@ -304,10 +304,10 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() - if tt.metricsSet == testDataSetDefault { + if test.metricsSet == testDataSetDefault { assert.Equal(t, defaultMetricsCount, ms.Len()) } - if tt.metricsSet == testDataSetAll { + if test.metricsSet == testDataSetAll { assert.Equal(t, allMetricsCount, ms.Len()) } validatedMetrics := make(map[string]bool) @@ -320,7 +320,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of bytes read from the cache or proxied server.", ms.At(i).Description()) assert.Equal(t, "bytes", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -370,7 +370,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of responses read from the cache or proxied server.", ms.At(i).Description()) assert.Equal(t, "responses", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -390,7 +390,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of NGINX config reloads.", ms.At(i).Description()) assert.Equal(t, "reloads", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -404,7 +404,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of connections.", ms.At(i).Description()) assert.Equal(t, "connections", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -436,7 +436,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of connections to an endpoint with a limit_conn directive.", ms.At(i).Description()) assert.Equal(t, "connections", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -456,7 +456,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of requests to an endpoint with a limit_req directive.", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -476,7 +476,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of HTTP byte IO.", ms.At(i).Description()) assert.Equal(t, "bytes", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -499,7 +499,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of requests completed without sending a response.", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -537,7 +537,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of client requests received from clients.", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -569,7 +569,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The number of responses, grouped by status code range.", ms.At(i).Description()) assert.Equal(t, "responses", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -592,7 +592,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of client requests received from clients.", ms.At(i).Description()) assert.Equal(t, "responses", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -630,7 +630,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of byte IO per HTTP upstream peer.", ms.At(i).Description()) assert.Equal(t, "bytes", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -752,7 +752,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of health check requests made to a HTTP upstream peer.", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -781,7 +781,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of client requests forwarded to the HTTP upstream peer.", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -831,7 +831,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of responses obtained from the HTTP upstream peer grouped by status range.", ms.At(i).Description()) assert.Equal(t, "responses", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -887,7 +887,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "Number of times the server became unavailable for client requests (“unavail”).", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -931,7 +931,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of requests rejected due to the queue overflow.", ms.At(i).Description()) assert.Equal(t, "responses", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1036,7 +1036,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeDouble, dp.ValueType()) - assert.InDelta(t, float64(1), dp.DoubleValue(), 0.01) + assert.Equal(t, float64(1), dp.DoubleValue()) attrVal, ok := dp.Attributes().Get("nginx.zone.name") assert.True(t, ok) assert.EqualValues(t, "nginx.zone.name-val", attrVal.Str()) @@ -1047,7 +1047,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The number of attempts to allocate memory of specified size.", ms.At(i).Description()) assert.Equal(t, "allocations", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1106,7 +1106,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of SSL certificate verification failures.", ms.At(i).Description()) assert.Equal(t, "certificates", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1123,7 +1123,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of SSL handshakes.", ms.At(i).Description()) assert.Equal(t, "handshakes", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1143,7 +1143,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of Stream byte IO.", ms.At(i).Description()) assert.Equal(t, "bytes", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1163,7 +1163,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of connections accepted from clients.", ms.At(i).Description()) assert.Equal(t, "connections", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1180,7 +1180,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "Total number of connections completed without creating a session.", ms.At(i).Description()) assert.Equal(t, "connections", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1212,7 +1212,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of completed sessions.", ms.At(i).Description()) assert.Equal(t, "sessions", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1232,7 +1232,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of Stream Upstream Peer byte IO.", ms.At(i).Description()) assert.Equal(t, "bytes", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1309,7 +1309,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of client connections forwarded to this stream upstream peer.", ms.At(i).Description()) assert.Equal(t, "connections", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1335,7 +1335,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of stream upstream peers grouped by state.", ms.At(i).Description()) assert.Equal(t, "peers", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1358,7 +1358,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of unsuccessful attempts to communicate with the stream upstream peer.", ms.At(i).Description()) assert.Equal(t, "peers", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1381,7 +1381,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "The total number of health check requests made to the stream upstream peer.", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1434,7 +1434,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "Current state of upstream peers in deployment. If any of the upstream peers in the deployment match the given state then the value will be 1. If no upstream peer is a match then the value will be 0.", ms.At(i).Description()) assert.Equal(t, "deployments", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) @@ -1487,7 +1487,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "How many times the server became unavailable for client connections (state “unavail”) due to the number of unsuccessful attempts reaching the max_fails threshold.", ms.At(i).Description()) assert.Equal(t, "requests", ms.At(i).Unit()) - assert.True(t, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) diff --git a/internal/file/file_manager_service.go b/internal/file/file_manager_service.go index 6a460918c4..04b2611d65 100644 --- a/internal/file/file_manager_service.go +++ b/internal/file/file_manager_service.go @@ -11,6 +11,7 @@ import ( "fmt" "log/slog" "os" + "sync" "sync/atomic" "github.com/nginx/agent/v3/internal/model" @@ -45,6 +46,9 @@ type ( Rollback(ctx context.Context, instanceID string) error UpdateFile(ctx context.Context, instanceID string, fileToUpdate *mpi.File) error ClearCache() + UpdateCurrentFilesOnDisk(updateFiles map[string]*mpi.File) + DetermineFileActions(currentFiles, modifiedFiles map[string]*mpi.File) (map[string]*mpi.File, + map[string][]byte, error) SetIsConnected(isConnected bool) } ) @@ -54,8 +58,13 @@ type FileManagerService struct { agentConfig *config.Config isConnected *atomic.Bool fileOperator fileOperator - filesCache map[string]*mpi.File // key is file path - fileContentsCache map[string][]byte // key is file path + // map of files and the actions performed on them during config apply + fileActions map[string]*mpi.File // key is file path + // map of the contents of files which have been updated or deleted during config apply, used during rollback + rollbackFileContents map[string][]byte // key is file path + // map of the files currently on disk, used to determine the file action during config apply + currentFilesOnDisk map[string]*mpi.File // key is file path + filesMutex sync.RWMutex } func NewFileManagerService(fileServiceClient mpi.FileServiceClient, agentConfig *config.Config) *FileManagerService { @@ -63,12 +72,13 @@ func NewFileManagerService(fileServiceClient mpi.FileServiceClient, agentConfig isConnected.Store(false) return &FileManagerService{ - fileServiceClient: fileServiceClient, - agentConfig: agentConfig, - fileOperator: NewFileOperator(), - filesCache: make(map[string]*mpi.File), - fileContentsCache: make(map[string][]byte), - isConnected: isConnected, + fileServiceClient: fileServiceClient, + agentConfig: agentConfig, + fileOperator: NewFileOperator(), + fileActions: make(map[string]*mpi.File), + rollbackFileContents: make(map[string][]byte), + currentFilesOnDisk: make(map[string]*mpi.File), + isConnected: isConnected, } } @@ -218,7 +228,9 @@ func (fms *FileManagerService) ConfigApply(ctx context.Context, return model.Error, allowedErr } - diffFiles, fileContent, compareErr := files.CompareFileHash(fileOverview) + diffFiles, fileContent, compareErr := fms.DetermineFileActions(fms.currentFilesOnDisk, + files.ConvertToMapOfFiles(fileOverview.GetFiles())) + if compareErr != nil { return model.Error, compareErr } @@ -227,40 +239,51 @@ func (fms *FileManagerService) ConfigApply(ctx context.Context, return model.NoChange, nil } - fms.fileContentsCache = fileContent - fms.filesCache = diffFiles + fms.rollbackFileContents = fileContent + fms.fileActions = diffFiles fileErr := fms.executeFileActions(ctx) if fileErr != nil { return model.RollbackRequired, fileErr } + // Update map of current files on disk + fms.UpdateCurrentFilesOnDisk(files.ConvertToMapOfFiles(fileOverview.GetFiles())) + return model.OK, nil } func (fms *FileManagerService) ClearCache() { - clear(fms.fileContentsCache) - clear(fms.filesCache) + clear(fms.rollbackFileContents) + clear(fms.fileActions) } func (fms *FileManagerService) Rollback(ctx context.Context, instanceID string) error { slog.InfoContext(ctx, "Rolling back config for instance", "instanceid", instanceID) - for _, file := range fms.filesCache { + fms.filesMutex.Lock() + defer fms.filesMutex.Unlock() + for _, file := range fms.fileActions { switch file.GetAction() { case mpi.File_FILE_ACTION_ADD: if err := os.Remove(file.GetFileMeta().GetName()); err != nil && !os.IsNotExist(err) { return fmt.Errorf("error deleting file: %s error: %w", file.GetFileMeta().GetName(), err) } + // currentFilesOnDisk needs to be updated after rollback action is performed + delete(fms.currentFilesOnDisk, file.GetFileMeta().GetName()) + continue case mpi.File_FILE_ACTION_DELETE, mpi.File_FILE_ACTION_UPDATE: - content := fms.fileContentsCache[file.GetFileMeta().GetName()] + content := fms.rollbackFileContents[file.GetFileMeta().GetName()] err := fms.fileOperator.Write(ctx, content, file.GetFileMeta()) if err != nil { return err } + // currentFilesOnDisk needs to be updated after rollback action is performed + file.GetFileMeta().Hash = files.GenerateHash(content) + fms.currentFilesOnDisk[file.GetFileMeta().GetName()] = file case mpi.File_FILE_ACTION_UNSPECIFIED, mpi.File_FILE_ACTION_UNCHANGED: fallthrough default: @@ -272,7 +295,7 @@ func (fms *FileManagerService) Rollback(ctx context.Context, instanceID string) } func (fms *FileManagerService) executeFileActions(ctx context.Context) error { - for _, file := range fms.filesCache { + for _, file := range fms.fileActions { switch file.GetAction() { case mpi.File_FILE_ACTION_DELETE: if err := os.Remove(file.GetFileMeta().GetName()); err != nil && !os.IsNotExist(err) { @@ -336,7 +359,7 @@ func (fms *FileManagerService) validateFileHash(filePath string) error { } fileHash := files.GenerateHash(content) - if fileHash != fms.filesCache[filePath].GetFileMeta().GetHash() { + if fileHash != fms.fileActions[filePath].GetFileMeta().GetHash() { return fmt.Errorf("error writing file, file hash does not match for file %s", filePath) } @@ -353,3 +376,76 @@ func (fms *FileManagerService) checkAllowedDirectory(checkFiles []*mpi.File) err return nil } + +// DetermineFileActions compares two sets of files to determine the file action for each file. Returns a map of files +// that have changed and a map of the contents for each updated and deleted file. Key to both maps is file path +// nolint: revive +func (fms *FileManagerService) DetermineFileActions(currentFiles, modifiedFiles map[string]*mpi.File) ( + map[string]*mpi.File, map[string][]byte, error, +) { + fms.filesMutex.Lock() + defer fms.filesMutex.Unlock() + // Go doesn't allow address of numeric constant + addAction := mpi.File_FILE_ACTION_ADD + updateAction := mpi.File_FILE_ACTION_UPDATE + deleteAction := mpi.File_FILE_ACTION_DELETE + unchangedAction := mpi.File_FILE_ACTION_UNCHANGED + + fileDiff := make(map[string]*mpi.File) // Files that have changed, key is file name + fileContents := make(map[string][]byte) // contents of the file, key is file name + + // if file is in currentFiles but not in modified files, file has been deleted + // copy contents, set file action + for _, currentFile := range currentFiles { + fileName := currentFile.GetFileMeta().GetName() + _, ok := modifiedFiles[fileName] + + if !ok { + fileContent, readErr := os.ReadFile(fileName) + if readErr != nil { + return nil, nil, fmt.Errorf("error reading file %s, error: %w", fileName, readErr) + } + fileContents[fileName] = fileContent + currentFile.Action = &deleteAction + fileDiff[currentFile.GetFileMeta().GetName()] = currentFile + } + } + + for _, file := range modifiedFiles { + fileName := file.GetFileMeta().GetName() + currentFile, ok := currentFiles[file.GetFileMeta().GetName()] + // default to unchanged action + file.Action = &unchangedAction + // if file doesn't exist in the current files, file has been added + // set file action + if !ok { + file.Action = &addAction + fileDiff[file.GetFileMeta().GetName()] = file + // if file currently exists and file hash is different, file has been updated + // copy contents, set file action + } else if file.GetFileMeta().GetHash() != currentFile.GetFileMeta().GetHash() { + fileContent, readErr := os.ReadFile(fileName) + if readErr != nil { + return nil, nil, fmt.Errorf("error generating hash for file %s, error: %w", fileName, readErr) + } + file.Action = &updateAction + fileContents[fileName] = fileContent + fileDiff[file.GetFileMeta().GetName()] = file + } + } + + return fileDiff, fileContents, nil +} + +// UpdateCurrentFilesOnDisk updates the FileManagerService currentFilesOnDisk slice which contains the files +// currently on disk +func (fms *FileManagerService) UpdateCurrentFilesOnDisk(currentFiles map[string]*mpi.File) { + fms.filesMutex.Lock() + defer fms.filesMutex.Unlock() + + clear(fms.currentFilesOnDisk) + + for _, file := range currentFiles { + fms.currentFilesOnDisk[file.GetFileMeta().GetName()] = file + } +} diff --git a/internal/file/file_manager_service_test.go b/internal/file/file_manager_service_test.go index 75ee947a73..e3bd29d2cb 100644 --- a/internal/file/file_manager_service_test.go +++ b/internal/file/file_manager_service_test.go @@ -66,14 +66,13 @@ func TestFileManagerService_UpdateFile(t *testing.T) { func TestFileManagerService_ConfigApply_Add(t *testing.T) { ctx := context.Background() tempDir := t.TempDir() - addAction := mpi.File_FILE_ACTION_ADD filePath := filepath.Join(tempDir, "nginx.conf") fileContent := []byte("location /test {\n return 200 \"Test location\\n\";\n}") fileHash := files.GenerateHash(fileContent) defer helpers.RemoveFileWithErrorCheck(t, filePath) - overview := protos.FileOverview(filePath, fileHash, &addAction) + overview := protos.FileOverview(filePath, fileHash) fakeFileServiceClient := &v1fakes.FakeFileServiceClient{} fakeFileServiceClient.GetOverviewReturns(&mpi.GetOverviewResponse{ @@ -95,23 +94,35 @@ func TestFileManagerService_ConfigApply_Add(t *testing.T) { data, readErr := os.ReadFile(filePath) require.NoError(t, readErr) assert.Equal(t, fileContent, data) - assert.Equal(t, fileManagerService.filesCache[filePath], overview.GetFiles()[0]) + assert.Equal(t, fileManagerService.fileActions[filePath], overview.GetFiles()[0]) } func TestFileManagerService_ConfigApply_Update(t *testing.T) { ctx := context.Background() tempDir := t.TempDir() - updateAction := mpi.File_FILE_ACTION_UPDATE fileContent := []byte("location /test {\n return 200 \"Test location\\n\";\n}") previousFileContent := []byte("some test data") + previousFileHash := files.GenerateHash(previousFileContent) fileHash := files.GenerateHash(fileContent) tempFile := helpers.CreateFileWithErrorCheck(t, tempDir, "nginx.conf") _, writeErr := tempFile.Write(previousFileContent) require.NoError(t, writeErr) defer helpers.RemoveFileWithErrorCheck(t, tempFile.Name()) - overview := protos.FileOverview(tempFile.Name(), fileHash, &updateAction) + filesOnDisk := map[string]*mpi.File{ + tempFile.Name(): { + FileMeta: &mpi.FileMeta{ + Name: tempFile.Name(), + Hash: previousFileHash, + ModifiedTime: timestamppb.Now(), + Permissions: "0640", + Size: 0, + }, + }, + } + + overview := protos.FileOverview(tempFile.Name(), fileHash) fakeFileServiceClient := &v1fakes.FakeFileServiceClient{} fakeFileServiceClient.GetOverviewReturns(&mpi.GetOverviewResponse{ @@ -125,6 +136,7 @@ func TestFileManagerService_ConfigApply_Update(t *testing.T) { agentConfig := types.AgentConfig() agentConfig.AllowedDirectories = []string{tempDir} fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig) + fileManagerService.UpdateCurrentFilesOnDisk(filesOnDisk) request := protos.CreateConfigApplyRequest(overview) @@ -134,34 +146,56 @@ func TestFileManagerService_ConfigApply_Update(t *testing.T) { data, readErr := os.ReadFile(tempFile.Name()) require.NoError(t, readErr) assert.Equal(t, fileContent, data) - assert.Equal(t, fileManagerService.fileContentsCache[tempFile.Name()], previousFileContent) - assert.Equal(t, fileManagerService.filesCache[tempFile.Name()], overview.GetFiles()[0]) + assert.Equal(t, fileManagerService.rollbackFileContents[tempFile.Name()], previousFileContent) + assert.Equal(t, fileManagerService.fileActions[tempFile.Name()], overview.GetFiles()[0]) } func TestFileManagerService_ConfigApply_Delete(t *testing.T) { ctx := context.Background() tempDir := t.TempDir() - deleteAction := mpi.File_FILE_ACTION_DELETE fileContent := []byte("location /test {\n return 200 \"Test location\\n\";\n}") tempFile := helpers.CreateFileWithErrorCheck(t, tempDir, "nginx.conf") _, writeErr := tempFile.Write(fileContent) require.NoError(t, writeErr) - overview := protos.FileOverview(tempFile.Name(), files.GenerateHash(fileContent), &deleteAction) + tempFile2 := helpers.CreateFileWithErrorCheck(t, tempDir, "test.conf") + overview := protos.FileOverview(tempFile2.Name(), files.GenerateHash(fileContent)) + + filesOnDisk := map[string]*mpi.File{ + tempFile.Name(): { + FileMeta: &mpi.FileMeta{ + Name: tempFile.Name(), + Hash: files.GenerateHash(fileContent), + ModifiedTime: timestamppb.Now(), + Permissions: "0640", + Size: 0, + }, + }, + } fakeFileServiceClient := &v1fakes.FakeFileServiceClient{} agentConfig := types.AgentConfig() agentConfig.AllowedDirectories = []string{tempDir} fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig) + fileManagerService.UpdateCurrentFilesOnDisk(filesOnDisk) request := protos.CreateConfigApplyRequest(overview) + fakeFileServiceClient.GetOverviewReturns(&mpi.GetOverviewResponse{ + Overview: overview, + }, nil) + fakeFileServiceClient.GetFileReturns(&mpi.GetFileResponse{ + Contents: &mpi.FileContents{ + Contents: fileContent, + }, + }, nil) + writeStatus, err := fileManagerService.ConfigApply(ctx, request) require.NoError(t, err) assert.NoFileExists(t, tempFile.Name()) - assert.Equal(t, fileManagerService.fileContentsCache[tempFile.Name()], fileContent) - assert.Equal(t, fileManagerService.filesCache[tempFile.Name()], overview.GetFiles()[0]) + assert.Equal(t, fileManagerService.rollbackFileContents[tempFile.Name()], fileContent) + assert.Equal(t, fileManagerService.fileActions[tempFile.Name()], filesOnDisk[tempFile.Name()]) assert.Equal(t, model.OK, writeStatus) } @@ -221,15 +255,15 @@ func TestFileManagerService_ClearCache(t *testing.T) { "file/path/test.conf": []byte("some test data"), } - fileManagerService.filesCache = filesCache - fileManagerService.fileContentsCache = contentsCache - assert.NotEmpty(t, fileManagerService.filesCache) - assert.NotEmpty(t, fileManagerService.fileContentsCache) + fileManagerService.fileActions = filesCache + fileManagerService.rollbackFileContents = contentsCache + assert.NotEmpty(t, fileManagerService.fileActions) + assert.NotEmpty(t, fileManagerService.rollbackFileContents) fileManagerService.ClearCache() - assert.Empty(t, fileManagerService.filesCache) - assert.Empty(t, fileManagerService.fileContentsCache) + assert.Empty(t, fileManagerService.fileActions) + assert.Empty(t, fileManagerService.rollbackFileContents) } func TestFileManagerService_Rollback(t *testing.T) { @@ -306,8 +340,8 @@ func TestFileManagerService_Rollback(t *testing.T) { instanceID := protos.GetNginxOssInstance([]string{}).GetInstanceMeta().GetInstanceId() fakeFileServiceClient := &v1fakes.FakeFileServiceClient{} fileManagerService := NewFileManagerService(fakeFileServiceClient, types.AgentConfig()) - fileManagerService.fileContentsCache = fileContentCache - fileManagerService.filesCache = filesCache + fileManagerService.rollbackFileContents = fileContentCache + fileManagerService.fileActions = filesCache err := fileManagerService.Rollback(ctx, instanceID) require.NoError(t, err) @@ -326,6 +360,120 @@ func TestFileManagerService_Rollback(t *testing.T) { defer helpers.RemoveFileWithErrorCheck(t, deleteFilePath) } +func TestFileManagerService_DetermineFileActions(t *testing.T) { + // Go doesn't allow address of numeric constant + addAction := mpi.File_FILE_ACTION_ADD + updateAction := mpi.File_FILE_ACTION_UPDATE + deleteAction := mpi.File_FILE_ACTION_DELETE + // unchangedAction := mpi.File_FILE_ACTION_UNCHANGED + + tempDir := os.TempDir() + + deleteTestFile := helpers.CreateFileWithErrorCheck(t, tempDir, "nginx_delete.conf") + defer helpers.RemoveFileWithErrorCheck(t, deleteTestFile.Name()) + fileContent, readErr := os.ReadFile("../../test/config/nginx/nginx.conf") + require.NoError(t, readErr) + err := os.WriteFile(deleteTestFile.Name(), fileContent, 0o600) + require.NoError(t, err) + + updateTestFile := helpers.CreateFileWithErrorCheck(t, tempDir, "nginx_update.conf") + defer helpers.RemoveFileWithErrorCheck(t, updateTestFile.Name()) + updatedFileContent := []byte("test update file") + updateErr := os.WriteFile(updateTestFile.Name(), updatedFileContent, 0o600) + require.NoError(t, updateErr) + + addTestFileName := tempDir + "/nginx_add.conf" + + tests := []struct { + expectedError error + modifiedFiles map[string]*mpi.File + currentFiles map[string]*mpi.File + expectedCache map[string]*mpi.File + expectedContent map[string][]byte + name string + }{ + { + name: "Test 1: Add, Update & Delete Files", + modifiedFiles: map[string]*mpi.File{ + addTestFileName: { + FileMeta: protos.FileMeta(addTestFileName, files.GenerateHash(fileContent)), + }, + updateTestFile.Name(): { + FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(updatedFileContent)), + }, + }, + currentFiles: map[string]*mpi.File{ + deleteTestFile.Name(): { + FileMeta: protos.FileMeta(deleteTestFile.Name(), files.GenerateHash(fileContent)), + }, + updateTestFile.Name(): { + FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(fileContent)), + }, + }, + expectedCache: map[string]*mpi.File{ + deleteTestFile.Name(): { + FileMeta: protos.FileMeta(deleteTestFile.Name(), files.GenerateHash(fileContent)), + Action: &deleteAction, + }, + updateTestFile.Name(): { + FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(updatedFileContent)), + Action: &updateAction, + }, + addTestFileName: { + FileMeta: protos.FileMeta(addTestFileName, files.GenerateHash(fileContent)), + Action: &addAction, + }, + }, + expectedContent: map[string][]byte{ + deleteTestFile.Name(): fileContent, + updateTestFile.Name(): updatedFileContent, + }, + expectedError: nil, + }, + { + name: "Test 2: Files same as on disk", + modifiedFiles: map[string]*mpi.File{ + addTestFileName: { + FileMeta: protos.FileMeta(addTestFileName, files.GenerateHash(fileContent)), + }, + updateTestFile.Name(): { + FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(fileContent)), + }, + deleteTestFile.Name(): { + FileMeta: protos.FileMeta(deleteTestFile.Name(), files.GenerateHash(fileContent)), + }, + }, + currentFiles: map[string]*mpi.File{ + deleteTestFile.Name(): { + FileMeta: protos.FileMeta(deleteTestFile.Name(), files.GenerateHash(fileContent)), + }, + updateTestFile.Name(): { + FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(fileContent)), + }, + addTestFileName: { + FileMeta: protos.FileMeta(addTestFileName, files.GenerateHash(fileContent)), + }, + }, + expectedCache: make(map[string]*mpi.File), + expectedContent: make(map[string][]byte), + expectedError: nil, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + fakeFileServiceClient := &v1fakes.FakeFileServiceClient{} + fileManagerService := NewFileManagerService(fakeFileServiceClient, types.AgentConfig()) + diff, contents, fileActionErr := fileManagerService.DetermineFileActions(test.currentFiles, + test.modifiedFiles) + + require.NoError(tt, fileActionErr) + assert.Equal(tt, test.expectedContent, contents) + assert.Equal(tt, test.expectedCache, diff) + }) + } +} + func TestFileManagerService_fileActions(t *testing.T) { ctx := context.Background() tempDir := t.TempDir() @@ -401,7 +549,7 @@ func TestFileManagerService_fileActions(t *testing.T) { }, nil) fileManagerService := NewFileManagerService(fakeFileServiceClient, types.AgentConfig()) - fileManagerService.filesCache = filesCache + fileManagerService.fileActions = filesCache actionErr := fileManagerService.executeFileActions(ctx) require.NoError(t, actionErr) diff --git a/internal/file/file_plugin.go b/internal/file/file_plugin.go index 7aa962677b..aee199ff57 100644 --- a/internal/file/file_plugin.go +++ b/internal/file/file_plugin.go @@ -10,6 +10,8 @@ import ( "fmt" "log/slog" + "github.com/nginx/agent/v3/pkg/files" + "github.com/google/uuid" mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" "github.com/nginx/agent/v3/internal/bus" @@ -68,8 +70,8 @@ func (fp *FilePlugin) Process(ctx context.Context, msg *bus.Message) { fp.handleConfigUploadRequest(ctx, msg) case bus.ConfigApplyRequestTopic: fp.handleConfigApplyRequest(ctx, msg) - case bus.ConfigApplySuccessfulTopic, bus.RollbackCompleteTopic: - fp.handleConfigApplyRollbackComplete(ctx, msg) + case bus.ConfigApplySuccessfulTopic, bus.ConfigApplyCompleteTopic: + fp.handleConfigApplyComplete(ctx, msg) case bus.ConfigApplyFailedTopic: fp.handleConfigApplyFailedRequest(ctx, msg) default: @@ -85,11 +87,11 @@ func (fp *FilePlugin) Subscriptions() []string { bus.ConfigApplyRequestTopic, bus.ConfigApplyFailedTopic, bus.ConfigApplySuccessfulTopic, - bus.RollbackCompleteTopic, + bus.ConfigApplyCompleteTopic, } } -func (fp *FilePlugin) handleConfigApplyRollbackComplete(ctx context.Context, msg *bus.Message) { +func (fp *FilePlugin) handleConfigApplyComplete(ctx context.Context, msg *bus.Message) { response, ok := msg.Data.(*mpi.DataPlaneResponse) if !ok { @@ -123,7 +125,7 @@ func (fp *FilePlugin) handleConfigApplyFailedRequest(ctx context.Context, msg *b fp.fileManagerService.ClearCache() fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: rollbackResponse}) - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: applyResponse}) + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplyCompleteTopic, Data: applyResponse}) return } @@ -153,12 +155,12 @@ func (fp *FilePlugin) handleConfigApplyRequest(ctx context.Context, msg *bus.Mes } configApplyRequest := request.ConfigApplyRequest + instanceID := configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId() writeStatus, err := fp.fileManagerService.ConfigApply(ctx, configApplyRequest) switch writeStatus { case model.NoChange: - instanceID := configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId() response = fp.createDataPlaneResponse( correlationID, mpi.CommandResponse_COMMAND_STATUS_OK, @@ -168,34 +170,33 @@ func (fp *FilePlugin) handleConfigApplyRequest(ctx context.Context, msg *bus.Mes ) fp.fileManagerService.ClearCache() - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplySuccessfulTopic, Data: instanceID}) + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplySuccessfulTopic, Data: response}) return case model.Error: slog.ErrorContext( ctx, "Failed to apply config changes", - "instance_id", configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), + "instance_id", instanceID, "error", err, ) response = fp.createDataPlaneResponse( correlationID, mpi.CommandResponse_COMMAND_STATUS_FAILURE, "Config apply failed", - configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), + instanceID, err.Error(), ) fp.fileManagerService.ClearCache() - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplyCompleteTopic, Data: response}) return case model.RollbackRequired: slog.ErrorContext( ctx, "Failed to apply config changes, rolling back", - "instance_id", configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), + "instance_id", instanceID, "error", err, ) @@ -203,24 +204,25 @@ func (fp *FilePlugin) handleConfigApplyRequest(ctx context.Context, msg *bus.Mes correlationID, mpi.CommandResponse_COMMAND_STATUS_ERROR, "Config apply failed, rolling back config", - configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), + instanceID, err.Error(), ) fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) rollbackErr := fp.fileManagerService.Rollback( ctx, - configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), + instanceID, ) if rollbackErr != nil { rollbackResponse := fp.createDataPlaneResponse( correlationID, mpi.CommandResponse_COMMAND_STATUS_FAILURE, "Config apply failed, rollback failed", - configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), + instanceID, rollbackErr.Error()) + fp.fileManagerService.ClearCache() - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: rollbackResponse}) + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplyCompleteTopic, Data: rollbackResponse}) return } @@ -229,18 +231,20 @@ func (fp *FilePlugin) handleConfigApplyRequest(ctx context.Context, msg *bus.Mes correlationID, mpi.CommandResponse_COMMAND_STATUS_FAILURE, "Config apply failed, rollback successful", - configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), + instanceID, err.Error()) + fp.fileManagerService.ClearCache() - fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: response}) + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplyCompleteTopic, Data: response}) return case model.OK: // Send WriteConfigSuccessfulTopic with Correlation and Instance ID for use by resource plugin data := &model.ConfigApplyMessage{ CorrelationID: correlationID, - InstanceID: configApplyRequest.GetOverview().GetConfigVersion().GetInstanceId(), + InstanceID: instanceID, } + fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.WriteConfigSuccessfulTopic, Data: data}) } } @@ -253,6 +257,8 @@ func (fp *FilePlugin) handleNginxConfigUpdate(ctx context.Context, msg *bus.Mess return } + fp.fileManagerService.UpdateCurrentFilesOnDisk(files.ConvertToMapOfFiles(nginxConfigContext.Files)) + err := fp.fileManagerService.UpdateOverview(ctx, nginxConfigContext.InstanceID, nginxConfigContext.Files) if err != nil { slog.ErrorContext( diff --git a/internal/file/file_plugin_test.go b/internal/file/file_plugin_test.go index 86fb4933c0..6775bd1ab3 100644 --- a/internal/file/file_plugin_test.go +++ b/internal/file/file_plugin_test.go @@ -55,7 +55,7 @@ func TestFilePlugin_Subscriptions(t *testing.T) { bus.ConfigApplyRequestTopic, bus.ConfigApplyFailedTopic, bus.ConfigApplySuccessfulTopic, - bus.RollbackCompleteTopic, + bus.ConfigApplyCompleteTopic, }, filePlugin.Subscriptions(), ) @@ -97,7 +97,6 @@ func TestFilePlugin_Process_NginxConfigUpdateTopic(t *testing.T) { func TestFilePlugin_Process_ConfigApplyRequestTopic(t *testing.T) { ctx := context.Background() tempDir := t.TempDir() - addAction := mpi.File_FILE_ACTION_ADD filePath := fmt.Sprintf("%s/nginx.conf", tempDir) fileContent := []byte("location /test {\n return 200 \"Test location\\n\";\n}") @@ -105,7 +104,7 @@ func TestFilePlugin_Process_ConfigApplyRequestTopic(t *testing.T) { message := &mpi.ManagementPlaneRequest{ Request: &mpi.ManagementPlaneRequest_ConfigApplyRequest{ - ConfigApplyRequest: protos.CreateConfigApplyRequest(protos.FileOverview(filePath, fileHash, &addAction)), + ConfigApplyRequest: protos.CreateConfigApplyRequest(protos.FileOverview(filePath, fileHash)), }, } fakeGrpcConnection := &grpcfakes.FakeGrpcConnectionInterface{} @@ -173,7 +172,7 @@ func TestFilePlugin_Process_ConfigApplyRequestTopic(t *testing.T) { assert.True(t, ok) case test.configApplyStatus == model.RollbackRequired: assert.Equal(t, bus.DataPlaneResponseTopic, messages[0].Topic) - assert.Len(t, messages, 2) + assert.Len(t, messages, 3) dataPlaneResponse, ok := messages[0].Data.(*mpi.DataPlaneResponse) assert.True(t, ok) assert.Equal( @@ -192,25 +191,28 @@ func TestFilePlugin_Process_ConfigApplyRequestTopic(t *testing.T) { dataPlaneResponse.GetCommandResponse().GetStatus()) case test.configApplyStatus == model.NoChange: assert.Len(t, messages, 2) + dataPlaneResponse, ok := messages[0].Data.(*mpi.DataPlaneResponse) assert.True(t, ok) + assert.Equal(t, bus.DataPlaneResponseTopic, messages[0].Topic) assert.Equal( t, mpi.CommandResponse_COMMAND_STATUS_OK, dataPlaneResponse.GetCommandResponse().GetStatus(), ) - instanceID, ok := messages[1].Data.(string) + response, ok := messages[1].Data.(*mpi.DataPlaneResponse) assert.True(t, ok) + assert.Equal(t, bus.ConfigApplySuccessfulTopic, messages[1].Topic) assert.Equal( t, - test.message.GetConfigApplyRequest().GetOverview().GetConfigVersion().GetInstanceId(), - instanceID, + mpi.CommandResponse_COMMAND_STATUS_OK, + response.GetCommandResponse().GetStatus(), ) case test.message == nil: assert.Empty(t, messages) default: - assert.Len(t, messages, 1) + assert.Len(t, messages, 2) dataPlaneResponse, ok := messages[0].Data.(*mpi.DataPlaneResponse) assert.True(t, ok) assert.Equal( @@ -430,7 +432,7 @@ func TestFilePlugin_Process_ConfigApplyFailedTopic(t *testing.T) { } } -func TestFilePlugin_Process_ConfigApllyRollbackCompleteTopic(t *testing.T) { +func TestFilePlugin_Process_ConfigApplyRollbackCompleteTopic(t *testing.T) { ctx := context.Background() instance := protos.GetNginxOssInstance([]string{}) mockFileManager := &filefakes.FakeFileManagerServiceInterface{} @@ -470,6 +472,4 @@ func TestFilePlugin_Process_ConfigApllyRollbackCompleteTopic(t *testing.T) { assert.Equal(t, expectedResponse.GetMessageMeta().GetCorrelationId(), response.GetMessageMeta().GetCorrelationId()) assert.Equal(t, expectedResponse.GetInstanceId(), response.GetInstanceId()) - - t.Logf("Messages: %v", messages) } diff --git a/internal/file/filefakes/fake_file_manager_service_interface.go b/internal/file/filefakes/fake_file_manager_service_interface.go index cfac6341be..96adf0e5ae 100644 --- a/internal/file/filefakes/fake_file_manager_service_interface.go +++ b/internal/file/filefakes/fake_file_manager_service_interface.go @@ -28,6 +28,22 @@ type FakeFileManagerServiceInterface struct { result1 model.WriteStatus result2 error } + DetermineFileActionsStub func(map[string]*v1.File, map[string]*v1.File) (map[string]*v1.File, map[string][]byte, error) + determineFileActionsMutex sync.RWMutex + determineFileActionsArgsForCall []struct { + arg1 map[string]*v1.File + arg2 map[string]*v1.File + } + determineFileActionsReturns struct { + result1 map[string]*v1.File + result2 map[string][]byte + result3 error + } + determineFileActionsReturnsOnCall map[int]struct { + result1 map[string]*v1.File + result2 map[string][]byte + result3 error + } RollbackStub func(context.Context, string) error rollbackMutex sync.RWMutex rollbackArgsForCall []struct { @@ -45,6 +61,11 @@ type FakeFileManagerServiceInterface struct { setIsConnectedArgsForCall []struct { arg1 bool } + UpdateCurrentFilesOnDiskStub func(map[string]*v1.File) + updateCurrentFilesOnDiskMutex sync.RWMutex + updateCurrentFilesOnDiskArgsForCall []struct { + arg1 map[string]*v1.File + } UpdateFileStub func(context.Context, string, *v1.File) error updateFileMutex sync.RWMutex updateFileArgsForCall []struct { @@ -164,6 +185,74 @@ func (fake *FakeFileManagerServiceInterface) ConfigApplyReturnsOnCall(i int, res }{result1, result2} } +func (fake *FakeFileManagerServiceInterface) DetermineFileActions(arg1 map[string]*v1.File, arg2 map[string]*v1.File) (map[string]*v1.File, map[string][]byte, error) { + fake.determineFileActionsMutex.Lock() + ret, specificReturn := fake.determineFileActionsReturnsOnCall[len(fake.determineFileActionsArgsForCall)] + fake.determineFileActionsArgsForCall = append(fake.determineFileActionsArgsForCall, struct { + arg1 map[string]*v1.File + arg2 map[string]*v1.File + }{arg1, arg2}) + stub := fake.DetermineFileActionsStub + fakeReturns := fake.determineFileActionsReturns + fake.recordInvocation("DetermineFileActions", []interface{}{arg1, arg2}) + fake.determineFileActionsMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2, ret.result3 + } + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 +} + +func (fake *FakeFileManagerServiceInterface) DetermineFileActionsCallCount() int { + fake.determineFileActionsMutex.RLock() + defer fake.determineFileActionsMutex.RUnlock() + return len(fake.determineFileActionsArgsForCall) +} + +func (fake *FakeFileManagerServiceInterface) DetermineFileActionsCalls(stub func(map[string]*v1.File, map[string]*v1.File) (map[string]*v1.File, map[string][]byte, error)) { + fake.determineFileActionsMutex.Lock() + defer fake.determineFileActionsMutex.Unlock() + fake.DetermineFileActionsStub = stub +} + +func (fake *FakeFileManagerServiceInterface) DetermineFileActionsArgsForCall(i int) (map[string]*v1.File, map[string]*v1.File) { + fake.determineFileActionsMutex.RLock() + defer fake.determineFileActionsMutex.RUnlock() + argsForCall := fake.determineFileActionsArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeFileManagerServiceInterface) DetermineFileActionsReturns(result1 map[string]*v1.File, result2 map[string][]byte, result3 error) { + fake.determineFileActionsMutex.Lock() + defer fake.determineFileActionsMutex.Unlock() + fake.DetermineFileActionsStub = nil + fake.determineFileActionsReturns = struct { + result1 map[string]*v1.File + result2 map[string][]byte + result3 error + }{result1, result2, result3} +} + +func (fake *FakeFileManagerServiceInterface) DetermineFileActionsReturnsOnCall(i int, result1 map[string]*v1.File, result2 map[string][]byte, result3 error) { + fake.determineFileActionsMutex.Lock() + defer fake.determineFileActionsMutex.Unlock() + fake.DetermineFileActionsStub = nil + if fake.determineFileActionsReturnsOnCall == nil { + fake.determineFileActionsReturnsOnCall = make(map[int]struct { + result1 map[string]*v1.File + result2 map[string][]byte + result3 error + }) + } + fake.determineFileActionsReturnsOnCall[i] = struct { + result1 map[string]*v1.File + result2 map[string][]byte + result3 error + }{result1, result2, result3} +} + func (fake *FakeFileManagerServiceInterface) Rollback(arg1 context.Context, arg2 string) error { fake.rollbackMutex.Lock() ret, specificReturn := fake.rollbackReturnsOnCall[len(fake.rollbackArgsForCall)] @@ -258,6 +347,38 @@ func (fake *FakeFileManagerServiceInterface) SetIsConnectedArgsForCall(i int) bo return argsForCall.arg1 } +func (fake *FakeFileManagerServiceInterface) UpdateCurrentFilesOnDisk(arg1 map[string]*v1.File) { + fake.updateCurrentFilesOnDiskMutex.Lock() + fake.updateCurrentFilesOnDiskArgsForCall = append(fake.updateCurrentFilesOnDiskArgsForCall, struct { + arg1 map[string]*v1.File + }{arg1}) + stub := fake.UpdateCurrentFilesOnDiskStub + fake.recordInvocation("UpdateCurrentFilesOnDisk", []interface{}{arg1}) + fake.updateCurrentFilesOnDiskMutex.Unlock() + if stub != nil { + fake.UpdateCurrentFilesOnDiskStub(arg1) + } +} + +func (fake *FakeFileManagerServiceInterface) UpdateCurrentFilesOnDiskCallCount() int { + fake.updateCurrentFilesOnDiskMutex.RLock() + defer fake.updateCurrentFilesOnDiskMutex.RUnlock() + return len(fake.updateCurrentFilesOnDiskArgsForCall) +} + +func (fake *FakeFileManagerServiceInterface) UpdateCurrentFilesOnDiskCalls(stub func(map[string]*v1.File)) { + fake.updateCurrentFilesOnDiskMutex.Lock() + defer fake.updateCurrentFilesOnDiskMutex.Unlock() + fake.UpdateCurrentFilesOnDiskStub = stub +} + +func (fake *FakeFileManagerServiceInterface) UpdateCurrentFilesOnDiskArgsForCall(i int) map[string]*v1.File { + fake.updateCurrentFilesOnDiskMutex.RLock() + defer fake.updateCurrentFilesOnDiskMutex.RUnlock() + argsForCall := fake.updateCurrentFilesOnDiskArgsForCall[i] + return argsForCall.arg1 +} + func (fake *FakeFileManagerServiceInterface) UpdateFile(arg1 context.Context, arg2 string, arg3 *v1.File) error { fake.updateFileMutex.Lock() ret, specificReturn := fake.updateFileReturnsOnCall[len(fake.updateFileArgsForCall)] @@ -396,10 +517,14 @@ func (fake *FakeFileManagerServiceInterface) Invocations() map[string][][]interf defer fake.clearCacheMutex.RUnlock() fake.configApplyMutex.RLock() defer fake.configApplyMutex.RUnlock() + fake.determineFileActionsMutex.RLock() + defer fake.determineFileActionsMutex.RUnlock() fake.rollbackMutex.RLock() defer fake.rollbackMutex.RUnlock() fake.setIsConnectedMutex.RLock() defer fake.setIsConnectedMutex.RUnlock() + fake.updateCurrentFilesOnDiskMutex.RLock() + defer fake.updateCurrentFilesOnDiskMutex.RUnlock() fake.updateFileMutex.RLock() defer fake.updateFileMutex.RUnlock() fake.updateOverviewMutex.RLock() diff --git a/internal/resource/resource_plugin.go b/internal/resource/resource_plugin.go index f916761f93..c3dc5ca40e 100644 --- a/internal/resource/resource_plugin.go +++ b/internal/resource/resource_plugin.go @@ -169,7 +169,7 @@ func (r *Resource) handleRollbackWrite(ctx context.Context, msg *bus.Message) { data.InstanceID, data.Error.Error()) r.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: rollbackResponse}) - r.messagePipe.Process(ctx, &bus.Message{Topic: bus.RollbackCompleteTopic, Data: applyResponse}) + r.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplyCompleteTopic, Data: applyResponse}) return } @@ -178,7 +178,7 @@ func (r *Resource) handleRollbackWrite(ctx context.Context, msg *bus.Message) { mpi.CommandResponse_COMMAND_STATUS_FAILURE, "Config apply failed, rollback successful", data.InstanceID, data.Error.Error()) - r.messagePipe.Process(ctx, &bus.Message{Topic: bus.RollbackCompleteTopic, Data: applyResponse}) + r.messagePipe.Process(ctx, &bus.Message{Topic: bus.ConfigApplyCompleteTopic, Data: applyResponse}) } func (*Resource) createDataPlaneResponse(correlationID string, status mpi.CommandResponse_CommandStatus, diff --git a/internal/resource/resource_plugin_test.go b/internal/resource/resource_plugin_test.go index 49f1bb0425..8f345f1ecb 100644 --- a/internal/resource/resource_plugin_test.go +++ b/internal/resource/resource_plugin_test.go @@ -201,7 +201,7 @@ func TestResource_Process_Rollback(t *testing.T) { }, }, rollbackErr: nil, - topic: []string{bus.RollbackCompleteTopic}, + topic: []string{bus.ConfigApplyCompleteTopic}, }, { name: "Test 2: Rollback Write Topic - Fail Status", @@ -214,7 +214,7 @@ func TestResource_Process_Rollback(t *testing.T) { }, }, rollbackErr: errors.New("error reloading"), - topic: []string{bus.RollbackCompleteTopic, bus.DataPlaneResponseTopic}, + topic: []string{bus.ConfigApplyCompleteTopic, bus.DataPlaneResponseTopic}, }, } @@ -235,7 +235,7 @@ func TestResource_Process_Rollback(t *testing.T) { resourcePlugin.Process(ctx, test.message) sort.Slice(messagePipe.GetMessages(), func(i, j int) bool { - return messagePipe.GetMessages()[i].Topic > messagePipe.GetMessages()[j].Topic + return messagePipe.GetMessages()[i].Topic < messagePipe.GetMessages()[j].Topic }) assert.Equal(tt, len(test.topic), len(messagePipe.GetMessages())) diff --git a/internal/watcher/watcher_plugin.go b/internal/watcher/watcher_plugin.go index f062d736ae..897d248fb6 100644 --- a/internal/watcher/watcher_plugin.go +++ b/internal/watcher/watcher_plugin.go @@ -111,7 +111,7 @@ func (w *Watcher) Process(ctx context.Context, msg *bus.Message) { w.handleConfigApplyRequest(ctx, msg) case bus.ConfigApplySuccessfulTopic: w.handleConfigApplySuccess(ctx, msg) - case bus.RollbackCompleteTopic: + case bus.ConfigApplyCompleteTopic: w.handleRollbackComplete(ctx, msg) default: slog.DebugContext(ctx, "Watcher plugin unknown topic", "topic", msg.Topic) @@ -122,7 +122,7 @@ func (*Watcher) Subscriptions() []string { return []string{ bus.ConfigApplyRequestTopic, bus.ConfigApplySuccessfulTopic, - bus.RollbackCompleteTopic, + bus.ConfigApplyCompleteTopic, } } diff --git a/internal/watcher/watcher_plugin_test.go b/internal/watcher/watcher_plugin_test.go index d7c6830975..bc539e9ee7 100644 --- a/internal/watcher/watcher_plugin_test.go +++ b/internal/watcher/watcher_plugin_test.go @@ -183,7 +183,7 @@ func TestWatcher_Process_RollbackCompleteTopic(t *testing.T) { } message := &bus.Message{ - Topic: bus.RollbackCompleteTopic, + Topic: bus.ConfigApplyCompleteTopic, Data: response, } @@ -202,7 +202,7 @@ func TestWatcher_Subscriptions(t *testing.T) { []string{ bus.ConfigApplyRequestTopic, bus.ConfigApplySuccessfulTopic, - bus.RollbackCompleteTopic, + bus.ConfigApplyCompleteTopic, }, watcherPlugin.Subscriptions(), ) diff --git a/pkg/files/file_helpers.go b/pkg/files/file_helpers.go index f9d3f70dda..6393a1fe1e 100644 --- a/pkg/files/file_helpers.go +++ b/pkg/files/file_helpers.go @@ -9,7 +9,6 @@ package files import ( "cmp" "fmt" - "log/slog" "os" "slices" "strconv" @@ -80,111 +79,8 @@ func GenerateHash(b []byte) string { return uuid.NewMD5(uuid.Nil, b).String() } -// CompareFileHash compares files from the FileOverview to files on disk and returns a map with the files that have -// changed and a map with the contents of those files. Key to both maps is file path -// nolint: revive,cyclop -func CompareFileHash(fileOverview *mpi.FileOverview) (fileDiff map[string]*mpi.File, - fileContents map[string][]byte, err error, -) { - fileDiff = make(map[string]*mpi.File) - fileContents = make(map[string][]byte) - - for _, file := range fileOverview.GetFiles() { - fileName := file.GetFileMeta().GetName() - switch file.GetAction() { - case mpi.File_FILE_ACTION_DELETE: - if _, err = os.Stat(fileName); os.IsNotExist(err) { - // File is already deleted, skip - continue - } - fileContent, readErr := os.ReadFile(fileName) - if readErr != nil { - return nil, nil, fmt.Errorf("error reading file %s, error: %w", fileName, readErr) - } - fileContents[fileName] = fileContent - fileDiff[fileName] = file - case mpi.File_FILE_ACTION_ADD: - if _, err = os.Stat(fileName); os.IsNotExist(err) { - // file is new, nothing to compare - fileDiff[fileName] = file - continue - } - // file already exists and needs to be updated instead - updateAction := mpi.File_FILE_ACTION_UPDATE - file.Action = &updateAction - - fallthrough - case mpi.File_FILE_ACTION_UPDATE: - fileContent, readErr := os.ReadFile(fileName) - if readErr != nil { - return nil, nil, fmt.Errorf("error generating hash for file %s, error: %w", fileName, readErr) - } - fileHash := GenerateHash(fileContent) - - if fileHash == file.GetFileMeta().GetHash() { - slog.Debug("file same on disk, skip", "filepath", fileName) - // file is same as on disk, skip - continue - } - - fileContents[fileName] = fileContent - fileDiff[fileName] = file - case mpi.File_FILE_ACTION_UNSPECIFIED, mpi.File_FILE_ACTION_UNCHANGED: - // FileAction is UNSPECIFIED or UNCHANGED skipping. Treat UNSPECIFIED as if it is UNCHANGED. - fallthrough - default: - continue - } - } - - return fileDiff, fileContents, nil -} - -// DetermineFileAction compares two lists of files, determines which file action is needed for each file, -// then returns a list of files with the action set for each file -func DetermineFileAction(currentFiles, modifiedFiles []*mpi.File) []*mpi.File { - // Go doesn't allow address of numeric constant - addAction := mpi.File_FILE_ACTION_ADD - updateAction := mpi.File_FILE_ACTION_UPDATE - deleteAction := mpi.File_FILE_ACTION_DELETE - unchangedAction := mpi.File_FILE_ACTION_UNCHANGED - - filesWithActions := make([]*mpi.File, 0, len(modifiedFiles)) - currentFilesMap := convertToMapOfFiles(currentFiles) - modifiedFilesMap := convertToMapOfFiles(modifiedFiles) - - // if file is in currentFiles but not in modified files, file has been deleted - for _, currentFile := range currentFilesMap { - _, ok := modifiedFilesMap[currentFile.GetFileMeta().GetName()] - if !ok { - currentFile.Action = &deleteAction - filesWithActions = append(filesWithActions, currentFile) - - continue - } - } - - for _, file := range modifiedFilesMap { - currentFile, ok := currentFilesMap[file.GetFileMeta().GetName()] - - // default to unchanged action - file.Action = &unchangedAction - // if file doesn't exist in the current files, file has been added - if !ok { - file.Action = &addAction - // if file currently exists and file hash is different, file has been updated - } else if file.GetFileMeta().GetHash() != currentFile.GetFileMeta().GetHash() { - file.Action = &updateAction - } - // if file exists and file hash matches, file is unchanged - filesWithActions = append(filesWithActions, file) - } - - return filesWithActions -} - -// convertToMapOfFiles converts a list of files to a map of files with the file name as the key -func convertToMapOfFiles(files []*mpi.File) map[string]*mpi.File { +// ConvertToMapOfFiles converts a list of files to a map of files with the file name as the key +func ConvertToMapOfFiles(files []*mpi.File) map[string]*mpi.File { filesMap := make(map[string]*mpi.File) for _, file := range files { filesMap[file.GetFileMeta().GetName()] = file diff --git a/pkg/files/file_helpers_test.go b/pkg/files/file_helpers_test.go index 63628c305d..4a2dcc9281 100644 --- a/pkg/files/file_helpers_test.go +++ b/pkg/files/file_helpers_test.go @@ -6,13 +6,9 @@ package files import ( - "cmp" "os" - "slices" "testing" - "google.golang.org/protobuf/proto" - "github.com/google/uuid" "github.com/nginx/agent/v3/test/protos" @@ -139,193 +135,3 @@ func TestGenerateHash(t *testing.T) { }) } } - -func TestCompareFileHash(t *testing.T) { - tempDir := os.TempDir() - - deleteTestFile := helpers.CreateFileWithErrorCheck(t, tempDir, "deleteTestFile") - defer helpers.RemoveFileWithErrorCheck(t, deleteTestFile.Name()) - expectedFileContent, readErr := os.ReadFile("../../test/config/nginx/nginx.conf") - require.NoError(t, readErr) - err := os.WriteFile(deleteTestFile.Name(), expectedFileContent, 0o600) - require.NoError(t, err) - - updateTestFile := helpers.CreateFileWithErrorCheck(t, tempDir, "updateTestFile") - defer helpers.RemoveFileWithErrorCheck(t, updateTestFile.Name()) - expectedUpdateFileContent := []byte("test update data") - updateErr := os.WriteFile(updateTestFile.Name(), expectedUpdateFileContent, 0o600) - require.NoError(t, updateErr) - - addTestFile := helpers.CreateFileWithErrorCheck(t, tempDir, "addTestFile") - defer helpers.RemoveFileWithErrorCheck(t, addTestFile.Name()) - addErr := os.WriteFile(addTestFile.Name(), expectedFileContent, 0o600) - require.NoError(t, addErr) - - // Go doesn't allow address of numeric constant - deleteAction := mpi.File_FILE_ACTION_DELETE - updateAction := mpi.File_FILE_ACTION_UPDATE - addAction := mpi.File_FILE_ACTION_ADD - - tests := []struct { - fileOverview *mpi.FileOverview - expectedDiff map[string]*mpi.File - expectedContents map[string][]byte - name string - }{ - { - name: "Test 1: Delete, Add & Update Files", - fileOverview: &mpi.FileOverview{ - Files: []*mpi.File{ - { - FileMeta: protos.FileMeta(deleteTestFile.Name(), GenerateHash(expectedFileContent)), - Action: &deleteAction, - }, - { - FileMeta: protos.FileMeta(updateTestFile.Name(), GenerateHash(expectedFileContent)), - Action: &updateAction, - }, - { - FileMeta: protos.FileMeta(tempDir+"random/new/file", GenerateHash(expectedFileContent)), - Action: &addAction, - }, - }, - ConfigVersion: &mpi.ConfigVersion{ - InstanceId: protos.GetNginxOssInstance([]string{}).GetInstanceMeta().GetInstanceId(), - Version: "a7d6580c-8ac9-376e-acde-b2cbed21d291", - }, - }, - expectedContents: map[string][]byte{ - deleteTestFile.Name(): expectedFileContent, - updateTestFile.Name(): expectedUpdateFileContent, - }, - expectedDiff: map[string]*mpi.File{ - deleteTestFile.Name(): { - FileMeta: protos.FileMeta(deleteTestFile.Name(), GenerateHash(expectedFileContent)), - Action: &deleteAction, - }, - updateTestFile.Name(): { - FileMeta: protos.FileMeta(updateTestFile.Name(), GenerateHash(expectedFileContent)), - Action: &updateAction, - }, - tempDir + "random/new/file": { - FileMeta: protos.FileMeta(tempDir+"random/new/file", GenerateHash(expectedFileContent)), - Action: &addAction, - }, - }, - }, - { - name: "Test 2: File Already Deleted, File Already Updated, File Already Added", - fileOverview: &mpi.FileOverview{ - Files: []*mpi.File{ - { - FileMeta: protos.FileMeta(tempDir+"deletedFile", GenerateHash(expectedFileContent)), - Action: &deleteAction, - }, - { - FileMeta: protos.FileMeta(updateTestFile.Name(), GenerateHash(expectedUpdateFileContent)), - Action: &updateAction, - }, - { - FileMeta: protos.FileMeta(addTestFile.Name(), GenerateHash(expectedUpdateFileContent)), - Action: &addAction, - }, - }, - ConfigVersion: protos.CreateConfigVersion(), - }, - expectedContents: map[string][]byte{ - addTestFile.Name(): expectedFileContent, - }, - expectedDiff: map[string]*mpi.File{ - addTestFile.Name(): { - FileMeta: protos.FileMeta(addTestFile.Name(), GenerateHash(expectedUpdateFileContent)), - Action: &updateAction, - }, - }, - }, - } - - for _, test := range tests { - t.Run(test.name, func(tt *testing.T) { - diff, contents, compareErr := CompareFileHash(test.fileOverview) - - assert.Equal(tt, test.expectedDiff, diff) - assert.Equal(tt, test.expectedContents, contents) - require.NoError(tt, compareErr) - }) - } -} - -func TestDetermineFileAction(t *testing.T) { - addAction := mpi.File_FILE_ACTION_ADD - updateAction := mpi.File_FILE_ACTION_UPDATE - deleteAction := mpi.File_FILE_ACTION_DELETE - unchangedAction := mpi.File_FILE_ACTION_UNCHANGED - - tempDir := os.TempDir() - deleteFile := tempDir + "deleteFile.conf" - addFile := tempDir + "addFile.conf" - updateFile := tempDir + "updateFile.conf" - unchangedFile := tempDir + "unchangedFile.conf" - - modifiedFileContent := []byte("test update data") - currentFileContent, readErr := os.ReadFile("../../test/config/nginx/nginx.conf") - require.NoError(t, readErr) - - currentFiles := []*mpi.File{ - { - FileMeta: protos.FileMeta(deleteFile, GenerateHash(currentFileContent)), - }, - { - FileMeta: protos.FileMeta(updateFile, GenerateHash(currentFileContent)), - }, - { - FileMeta: protos.FileMeta(unchangedFile, GenerateHash(currentFileContent)), - }, - } - - modifiedFiles := []*mpi.File{ - { - FileMeta: protos.FileMeta(updateFile, GenerateHash(modifiedFileContent)), - }, - { - FileMeta: protos.FileMeta(unchangedFile, GenerateHash(currentFileContent)), - }, - { - FileMeta: protos.FileMeta(addFile, GenerateHash(modifiedFileContent)), - }, - } - - expectedResult := []*mpi.File{ - { - FileMeta: protos.FileMeta(deleteFile, GenerateHash(currentFileContent)), - Action: &deleteAction, - }, - { - FileMeta: protos.FileMeta(updateFile, GenerateHash(modifiedFileContent)), - Action: &updateAction, - }, - { - FileMeta: protos.FileMeta(unchangedFile, GenerateHash(currentFileContent)), - Action: &unchangedAction, - }, - { - FileMeta: protos.FileMeta(addFile, GenerateHash(modifiedFileContent)), - Action: &addAction, - }, - } - - result := DetermineFileAction(currentFiles, modifiedFiles) - assert.Len(t, result, len(expectedResult)) - - slices.SortFunc(result, func(a, b *mpi.File) int { - return cmp.Compare(a.GetFileMeta().GetName(), b.GetFileMeta().GetName()) - }) - - slices.SortFunc(expectedResult, func(a, b *mpi.File) int { - return cmp.Compare(a.GetFileMeta().GetName(), b.GetFileMeta().GetName()) - }) - - for key, file := range result { - assert.True(t, proto.Equal(expectedResult[key], file)) - } -} diff --git a/test/integration/grpc_management_plane_api_test.go b/test/integration/grpc_management_plane_api_test.go index 9ee12e604f..6075003d9f 100644 --- a/test/integration/grpc_management_plane_api_test.go +++ b/test/integration/grpc_management_plane_api_test.go @@ -78,7 +78,9 @@ func setupConnectionTest(tb testing.TB, expectNoErrorsInLogs bool) func(tb testi require.NoError(tb, err) tb.Cleanup(func() { networkErr := containerNetwork.Remove(ctx) - tb.Logf("Error removing container network: %v", networkErr) + if networkErr != nil { + tb.Logf("Error removing container network: %v", networkErr) + } require.NoError(tb, networkErr) }) @@ -226,16 +228,17 @@ func TestGrpc_ConfigApply(t *testing.T) { assert.Equal(t, "Successfully updated all files", responses[0].GetCommandResponse().GetMessage()) t.Run("Test 1: No config changes", func(t *testing.T) { + clearManagementPlaneResponses(t) performConfigApply(t, nginxInstanceID) - - responses = getManagementPlaneResponses(t, 2) + responses = getManagementPlaneResponses(t, 1) t.Logf("Config apply responses: %v", responses) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply successful, no files to change", responses[1].GetCommandResponse().GetMessage()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply successful, no files to change", responses[0].GetCommandResponse().GetMessage()) }) t.Run("Test 2: Valid config", func(t *testing.T) { + clearManagementPlaneResponses(t) err := mockManagementPlaneGrpcContainer.CopyFileToContainer( ctx, "../config/nginx/nginx-with-test-location.conf", @@ -247,26 +250,27 @@ func TestGrpc_ConfigApply(t *testing.T) { performConfigApply(t, nginxInstanceID) if instanceType == "OSS" { - responses = getManagementPlaneResponses(t, 3) + responses = getManagementPlaneResponses(t, 1) t.Logf("Config apply responses: %v", responses) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[2].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply successful", responses[2].GetCommandResponse().GetMessage()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply successful", responses[0].GetCommandResponse().GetMessage()) } else { // NGINX Plus contains two extra Successfully updated all files responses as the NginxConfigContext // is updated, and the file overview is then updated - responses = getManagementPlaneResponses(t, 5) + responses = getManagementPlaneResponses(t, 3) t.Logf("Config apply responses: %v", responses) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[0].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply successful", responses[0].GetCommandResponse().GetMessage()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[1].GetCommandResponse().GetStatus()) + assert.Equal(t, "Successfully updated all files", responses[1].GetCommandResponse().GetMessage()) assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[2].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply successful", responses[2].GetCommandResponse().GetMessage()) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[3].GetCommandResponse().GetStatus()) - assert.Equal(t, "Successfully updated all files", responses[3].GetCommandResponse().GetMessage()) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_OK, responses[4].GetCommandResponse().GetStatus()) - assert.Equal(t, "Successfully updated all files", responses[4].GetCommandResponse().GetMessage()) + assert.Equal(t, "Successfully updated all files", responses[2].GetCommandResponse().GetMessage()) } }) t.Run("Test 3: Invalid config", func(t *testing.T) { + clearManagementPlaneResponses(t) err := mockManagementPlaneGrpcContainer.CopyFileToContainer( ctx, "../config/nginx/invalid-nginx.conf", @@ -278,52 +282,53 @@ func TestGrpc_ConfigApply(t *testing.T) { performConfigApply(t, nginxInstanceID) if instanceType == "OSS" { - responses = getManagementPlaneResponses(t, 5) + responses = getManagementPlaneResponses(t, 2) t.Logf("Config apply responses: %v", responses) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_ERROR, responses[3].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply failed, rolling back config", responses[3].GetCommandResponse().GetMessage()) - assert.Equal(t, configApplyErrorMessage, responses[3].GetCommandResponse().GetError()) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[4].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply failed, rollback successful", responses[4].GetCommandResponse().GetMessage()) - assert.Equal(t, configApplyErrorMessage, responses[4].GetCommandResponse().GetError()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_ERROR, responses[0].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply failed, rolling back config", responses[0].GetCommandResponse().GetMessage()) + assert.Equal(t, configApplyErrorMessage, responses[0].GetCommandResponse().GetError()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[1].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply failed, rollback successful", responses[1].GetCommandResponse().GetMessage()) + assert.Equal(t, configApplyErrorMessage, responses[1].GetCommandResponse().GetError()) } else { - responses = getManagementPlaneResponses(t, 7) + responses = getManagementPlaneResponses(t, 2) t.Logf("Config apply responses: %v", len(responses)) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_ERROR, responses[5].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply failed, rolling back config", responses[5].GetCommandResponse().GetMessage()) - assert.Equal(t, configApplyErrorMessage, responses[5].GetCommandResponse().GetError()) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[6].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply failed, rollback successful", responses[6].GetCommandResponse().GetMessage()) - assert.Equal(t, configApplyErrorMessage, responses[6].GetCommandResponse().GetError()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_ERROR, responses[0].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply failed, rolling back config", responses[0].GetCommandResponse().GetMessage()) + assert.Equal(t, configApplyErrorMessage, responses[0].GetCommandResponse().GetError()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[1].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply failed, rollback successful", responses[1].GetCommandResponse().GetMessage()) + assert.Equal(t, configApplyErrorMessage, responses[1].GetCommandResponse().GetError()) } }) t.Run("Test 4: File not in allowed directory", func(t *testing.T) { + clearManagementPlaneResponses(t) performInvalidConfigApply(t, nginxInstanceID) if instanceType == "OSS" { - responses = getManagementPlaneResponses(t, 6) + responses = getManagementPlaneResponses(t, 1) t.Logf("Config apply responses: %v", responses) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[5].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply failed", responses[5].GetCommandResponse().GetMessage()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[0].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply failed", responses[0].GetCommandResponse().GetMessage()) assert.Equal( t, "file not in allowed directories /unknown/nginx.conf", - responses[5].GetCommandResponse().GetError(), + responses[0].GetCommandResponse().GetError(), ) } else { - responses = getManagementPlaneResponses(t, 8) + responses = getManagementPlaneResponses(t, 1) t.Logf("Config apply responses: %v", responses) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[7].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply failed", responses[7].GetCommandResponse().GetMessage()) + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[0].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply failed", responses[0].GetCommandResponse().GetMessage()) assert.Equal( t, "file not in allowed directories /unknown/nginx.conf", - responses[7].GetCommandResponse().GetError(), + responses[0].GetCommandResponse().GetError(), ) } }) @@ -455,6 +460,18 @@ func getManagementPlaneResponses(t *testing.T, numberOfExpectedResponses int) [] return response } +func clearManagementPlaneResponses(t *testing.T) { + t.Helper() + + client := resty.New() + + url := fmt.Sprintf("http://%s/api/v1/responses/delete", mockManagementPlaneAPIAddress) + resp, err := client.R().EnableTrace().Get(url) + + require.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode()) +} + func verifyConnection(t *testing.T) string { t.Helper() diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index b481ec990e..194ff64e76 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -312,6 +312,16 @@ func (cs *CommandService) addResponseAndRequestEndpoints() { } }) + cs.server.GET("/api/v1/responses/delete", func(c *gin.Context) { + cs.dataPlaneResponsesMutex.Lock() + defer cs.dataPlaneResponsesMutex.Unlock() + + cs.dataPlaneResponses = make([]*mpi.DataPlaneResponse, 0) + + c.JSON(http.StatusOK, "cleared responses") + + }) + cs.server.POST("/api/v1/requests", func(c *gin.Context) { request := mpi.ManagementPlaneRequest{} body, err := io.ReadAll(c.Request.Body) @@ -392,7 +402,6 @@ func (cs *CommandService) findInstanceConfigFiles(instanceID string) (configFile if fileErr != nil { return fileErr } - file.Action = mpi.File_FILE_ACTION_UPDATE.Enum() slog.Debug( "File found:", diff --git a/test/protos/files.go b/test/protos/files.go index 715cb2bd1f..2065a4e8f1 100644 --- a/test/protos/files.go +++ b/test/protos/files.go @@ -21,7 +21,7 @@ func FileMeta(fileName, fileHash string) *mpi.FileMeta { } } -func FileOverview(filePath, fileHash string, action *mpi.File_FileAction) *mpi.FileOverview { +func FileOverview(filePath, fileHash string) *mpi.FileOverview { return &mpi.FileOverview{ Files: []*mpi.File{ { @@ -32,7 +32,6 @@ func FileOverview(filePath, fileHash string, action *mpi.File_FileAction) *mpi.F Permissions: "0640", Size: 0, }, - Action: action, }, }, ConfigVersion: CreateConfigVersion(), From afcb3fa8424c364e74b983f2baf1028f1216f2d2 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Thu, 24 Oct 2024 16:09:19 +0100 Subject: [PATCH 05/12] lint --- test/mock/grpc/mock_management_command_service.go | 1 - 1 file changed, 1 deletion(-) diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index 194ff64e76..bc1c9db8cf 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -319,7 +319,6 @@ func (cs *CommandService) addResponseAndRequestEndpoints() { cs.dataPlaneResponses = make([]*mpi.DataPlaneResponse, 0) c.JSON(http.StatusOK, "cleared responses") - }) cs.server.POST("/api/v1/requests", func(c *gin.Context) { From 12bc3b09c8997a43328272f9dcfa8b70a441777a Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Thu, 24 Oct 2024 16:13:17 +0100 Subject: [PATCH 06/12] lint --- .../grpc_management_plane_api_test.go | 35 ++++++------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/test/integration/grpc_management_plane_api_test.go b/test/integration/grpc_management_plane_api_test.go index 6075003d9f..7e5427915e 100644 --- a/test/integration/grpc_management_plane_api_test.go +++ b/test/integration/grpc_management_plane_api_test.go @@ -78,9 +78,7 @@ func setupConnectionTest(tb testing.TB, expectNoErrorsInLogs bool) func(tb testi require.NoError(tb, err) tb.Cleanup(func() { networkErr := containerNetwork.Remove(ctx) - if networkErr != nil { - tb.Logf("Error removing container network: %v", networkErr) - } + tb.Logf("Error removing container network: %v", networkErr) require.NoError(tb, networkErr) }) @@ -308,29 +306,16 @@ func TestGrpc_ConfigApply(t *testing.T) { clearManagementPlaneResponses(t) performInvalidConfigApply(t, nginxInstanceID) - if instanceType == "OSS" { - responses = getManagementPlaneResponses(t, 1) - t.Logf("Config apply responses: %v", responses) - - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[0].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply failed", responses[0].GetCommandResponse().GetMessage()) - assert.Equal( - t, - "file not in allowed directories /unknown/nginx.conf", - responses[0].GetCommandResponse().GetError(), - ) - } else { - responses = getManagementPlaneResponses(t, 1) - t.Logf("Config apply responses: %v", responses) + responses = getManagementPlaneResponses(t, 1) + t.Logf("Config apply responses: %v", responses) - assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[0].GetCommandResponse().GetStatus()) - assert.Equal(t, "Config apply failed", responses[0].GetCommandResponse().GetMessage()) - assert.Equal( - t, - "file not in allowed directories /unknown/nginx.conf", - responses[0].GetCommandResponse().GetError(), - ) - } + assert.Equal(t, mpi.CommandResponse_COMMAND_STATUS_FAILURE, responses[0].GetCommandResponse().GetStatus()) + assert.Equal(t, "Config apply failed", responses[0].GetCommandResponse().GetMessage()) + assert.Equal( + t, + "file not in allowed directories /unknown/nginx.conf", + responses[0].GetCommandResponse().GetError(), + ) }) } From 666f9135ed2f4aa913d710ff1c6dd81dd802925e Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Thu, 24 Oct 2024 16:20:14 +0100 Subject: [PATCH 07/12] generate --- .../internal/metadata/generated_metrics.go | 34 ++++++++----------- .../metadata/generated_resource_test.go | 10 +++--- .../metadata/generated_resource_test.go | 10 +++--- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/internal/collector/nginxossreceiver/internal/metadata/generated_metrics.go b/internal/collector/nginxossreceiver/internal/metadata/generated_metrics.go index 6b23c9102e..dfe01f264b 100644 --- a/internal/collector/nginxossreceiver/internal/metadata/generated_metrics.go +++ b/internal/collector/nginxossreceiver/internal/metadata/generated_metrics.go @@ -303,15 +303,17 @@ func newMetricNginxHTTPResponseStatus(cfg MetricConfig) metricNginxHTTPResponseS // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user config. type MetricsBuilder struct { - config MetricsBuilderConfig // config of the metrics builder. - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information. - metricNginxHTTPConn metricNginxHTTPConn - metricNginxHTTPConnCount metricNginxHTTPConnCount - metricNginxHTTPRequests metricNginxHTTPRequests - metricNginxHTTPResponseStatus metricNginxHTTPResponseStatus + config MetricsBuilderConfig // config of the metrics builder. + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information. + resourceAttributeIncludeFilter map[string]filter.Filter + resourceAttributeExcludeFilter map[string]filter.Filter + metricNginxHTTPConn metricNginxHTTPConn + metricNginxHTTPConnCount metricNginxHTTPConnCount + metricNginxHTTPRequests metricNginxHTTPRequests + metricNginxHTTPResponseStatus metricNginxHTTPResponseStatus } // metricBuilderOption applies changes to default metrics builder. @@ -369,22 +371,14 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption interface { - apply(pmetric.ResourceMetrics) -} - -type resourceMetricsOptionFunc func(pmetric.ResourceMetrics) - -func (rmof resourceMetricsOptionFunc) apply(rm pmetric.ResourceMetrics) { - rmof(rm) -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) // WithResource sets the provided resource on the emitted ResourceMetrics. // It's recommended to use ResourceBuilder to create the resource. func WithResource(res pcommon.Resource) ResourceMetricsOption { - return resourceMetricsOptionFunc(func(rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { res.CopyTo(rm.Resource()) - }) + } } // WithStartTimeOverride overrides start time for all the resource metrics data points. diff --git a/internal/collector/nginxossreceiver/internal/metadata/generated_resource_test.go b/internal/collector/nginxossreceiver/internal/metadata/generated_resource_test.go index f861ef1011..c35a461a5a 100644 --- a/internal/collector/nginxossreceiver/internal/metadata/generated_resource_test.go +++ b/internal/collector/nginxossreceiver/internal/metadata/generated_resource_test.go @@ -9,9 +9,9 @@ import ( ) func TestResourceBuilder(t *testing.T) { - for _, tt := range []string{"default", "all_set", "none_set"} { - t.Run(tt, func(t *testing.T) { - cfg := loadResourceAttributesConfig(t, tt) + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) rb := NewResourceBuilder(cfg) rb.SetInstanceID("instance.id-val") rb.SetInstanceType("instance.type-val") @@ -19,7 +19,7 @@ func TestResourceBuilder(t *testing.T) { res := rb.Emit() assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return empty Resource - switch tt { + switch test { case "default": assert.Equal(t, 2, res.Attributes().Len()) case "all_set": @@ -28,7 +28,7 @@ func TestResourceBuilder(t *testing.T) { assert.Equal(t, 0, res.Attributes().Len()) return default: - assert.Failf(t, "unexpected test case: %s", tt) + assert.Failf(t, "unexpected test case: %s", test) } val, ok := res.Attributes().Get("instance.id") diff --git a/internal/collector/nginxplusreceiver/internal/metadata/generated_resource_test.go b/internal/collector/nginxplusreceiver/internal/metadata/generated_resource_test.go index f861ef1011..c35a461a5a 100644 --- a/internal/collector/nginxplusreceiver/internal/metadata/generated_resource_test.go +++ b/internal/collector/nginxplusreceiver/internal/metadata/generated_resource_test.go @@ -9,9 +9,9 @@ import ( ) func TestResourceBuilder(t *testing.T) { - for _, tt := range []string{"default", "all_set", "none_set"} { - t.Run(tt, func(t *testing.T) { - cfg := loadResourceAttributesConfig(t, tt) + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) rb := NewResourceBuilder(cfg) rb.SetInstanceID("instance.id-val") rb.SetInstanceType("instance.type-val") @@ -19,7 +19,7 @@ func TestResourceBuilder(t *testing.T) { res := rb.Emit() assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return empty Resource - switch tt { + switch test { case "default": assert.Equal(t, 2, res.Attributes().Len()) case "all_set": @@ -28,7 +28,7 @@ func TestResourceBuilder(t *testing.T) { assert.Equal(t, 0, res.Attributes().Len()) return default: - assert.Failf(t, "unexpected test case: %s", tt) + assert.Failf(t, "unexpected test case: %s", test) } val, ok := res.Attributes().Get("instance.id") From 0f68549f44446e8cca3b0870bfc310e4329d71fc Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Fri, 25 Oct 2024 16:41:46 +0100 Subject: [PATCH 08/12] update sequence diagrams --- docs/architecture/config_apply.md | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/architecture/config_apply.md b/docs/architecture/config_apply.md index cd5bc33a18..d73ac6aea8 100644 --- a/docs/architecture/config_apply.md +++ b/docs/architecture/config_apply.md @@ -37,7 +37,7 @@ flowchart TB ``` -# Config Apply Sequence Diagram +# Config Apply Sequence Diagram ```mermaid sequenceDiagram participant Command Plugin as Command Plugin @@ -52,29 +52,47 @@ sequenceDiagram participant Watcher Plugin as Watcher Plugin Command Plugin -) Message Bus: ConfigApplyRequestTopic + Message Bus -)+ Watcher Plugin: ConfigApplyRequestTopic + Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(false) Message Bus -)+ File Plugin: ConfigApplyRequestTopic File Plugin ->>+ File Manager Service: ConfigApply(ctx, configApplyRequest) File Manager Service ->> File Manager Service: checkAllowedDirectory(checkFiles) - File Manager Service ->> File Manager Service: CompareFileHash(fileOverview) + File Manager Service ->> File Manager Service: DetermineFileActions(currentFilesOnDisk, modifiedFiles) File Manager Service ->> File Manager Service: executeFileActions(ctx) File Manager Service ->> File Operator: Write() File Operator -->> File Manager Service: error File Manager Service -->>- File Plugin: writeStatus, error alt no file changes rect rgb(66, 129, 164) + File Plugin ->> File Plugin: ClearCache() + File Plugin -) Message Bus: ConfigApplySuccessfulTopic + Message Bus -) File Plugin: ConfigApplySuccessfulTopic + Message Bus -) Watcher Plugin: ConfigApplySuccessfulTopic + Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) + File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_OK Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_OK end else has error rect rgb(166, 128, 140) + File Plugin ->> File Plugin: ClearCache() + File Plugin -) Message Bus: ConfigApplyCompleteTopic + Message Bus -) Watcher Plugin: ConfigApplyCompleteTopic + Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE end else rollback required rect rgb(144, 143, 217) File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_ERROR - File Plugin ->> File Manager Service: Rollback(ctx, instanceID) Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_ERROR + File Plugin ->> File Manager Service: Rollback(ctx, instanceID) + File Plugin ->> File Plugin: ClearCache() + File Plugin -) Message Bus: ConfigApplyCompleteTopic + Message Bus -) Watcher Plugin: ConfigApplyCompleteTopic + Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) + File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE + Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE end else no error rect rgb(66, 129, 164) @@ -99,12 +117,13 @@ sequenceDiagram alt no error rect rgb(66, 129, 164) Resource Plugin -) Message Bus: ConfigApplySuccessfulTopic - Resource Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_OK - Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_OK Message Bus -)+ File Plugin: ConfigApplySuccessfulTopic File Plugin ->>- File Plugin: clearCache() + File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_OK + Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_OK Message Bus -)+ Watcher Plugin: ConfigApplySuccessfulTopic Watcher Plugin ->>- Watcher Plugin: Reparse Config + Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) end else error rect rgb(146, 144, 199) From 73eb814ef2c97ada19542970de04beb4c9fb4e5f Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Fri, 25 Oct 2024 16:45:06 +0100 Subject: [PATCH 09/12] update flowchart --- docs/architecture/config_apply.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/config_apply.md b/docs/architecture/config_apply.md index d73ac6aea8..69f9883aeb 100644 --- a/docs/architecture/config_apply.md +++ b/docs/architecture/config_apply.md @@ -5,10 +5,10 @@ flowchart TB 0["Start"] --> 2["Receive Config Apply Request"] 2 --> 3{"File in allowed directory list?"} 3 -- No --> 4["Send Data Plane Response
COMMAND_STATUS_FAILURE"] - 3 -- Yes --> 5["Compare File Hash"] + 3 -- Yes --> 5["Determine File Actions"] 4 --> 6["Clear File Cache"] 6 --> 1["End"] - 5 --> 7{"Error Reading Files to Compare Hashes?"} + 5 --> 7{"Error Determining File Actions?"} 7 -- Yes --> 4 7 -- No --> 8["File Action Write, Add, Delete"] 8 --> 10{"File Changes ?"} From c426beecb608c9590db66fa4376fce9ff2012d75 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Fri, 25 Oct 2024 17:00:50 +0100 Subject: [PATCH 10/12] update rollback diagrams --- docs/architecture/config_apply.md | 11 +- docs/architecture/config_apply_rollback.md | 125 +++++++++++---------- 2 files changed, 75 insertions(+), 61 deletions(-) diff --git a/docs/architecture/config_apply.md b/docs/architecture/config_apply.md index 69f9883aeb..6a65f3b373 100644 --- a/docs/architecture/config_apply.md +++ b/docs/architecture/config_apply.md @@ -64,21 +64,22 @@ sequenceDiagram File Manager Service -->>- File Plugin: writeStatus, error alt no file changes rect rgb(66, 129, 164) - File Plugin ->> File Plugin: ClearCache() File Plugin -) Message Bus: ConfigApplySuccessfulTopic - Message Bus -) File Plugin: ConfigApplySuccessfulTopic Message Bus -) Watcher Plugin: ConfigApplySuccessfulTopic Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) + Message Bus -) File Plugin: ConfigApplySuccessfulTopic + File Plugin ->> File Plugin: ClearCache() File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_OK Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_OK end else has error rect rgb(166, 128, 140) - File Plugin ->> File Plugin: ClearCache() File Plugin -) Message Bus: ConfigApplyCompleteTopic Message Bus -) Watcher Plugin: ConfigApplyCompleteTopic Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) + Message Bus -) File Plugin: ConfigApplyCompleteTopic + File Plugin ->> File Plugin: ClearCache() File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE end @@ -87,10 +88,11 @@ sequenceDiagram File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_ERROR Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_ERROR File Plugin ->> File Manager Service: Rollback(ctx, instanceID) - File Plugin ->> File Plugin: ClearCache() File Plugin -) Message Bus: ConfigApplyCompleteTopic Message Bus -) Watcher Plugin: ConfigApplyCompleteTopic Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) + Message Bus -) File Plugin: ConfigApplyCompleteTopic + File Plugin ->> File Plugin: ClearCache() File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE end @@ -137,4 +139,5 @@ sequenceDiagram + ``` diff --git a/docs/architecture/config_apply_rollback.md b/docs/architecture/config_apply_rollback.md index 1e70ecf6f0..1d56542b26 100644 --- a/docs/architecture/config_apply_rollback.md +++ b/docs/architecture/config_apply_rollback.md @@ -25,66 +25,77 @@ flowchart TB # Config Apply Rollback Sequence Diagram ```mermaid sequenceDiagram - participant Command Plugin as Command Plugin - participant Message Bus as Message Bus - participant File Plugin as File Plugin - participant File Manager Service as File Manager Service - participant File Operator as File Operator - participant Resource Plugin as Resource Plugin - participant Resource Service as Resource Service - participant Instance Operator as Instance Operator - participant Log Tailer Operator as Log Tailer Operator + participant Command Plugin as Command Plugin + participant Message Bus as Message Bus + participant File Plugin as File Plugin + participant File Manager Service as File Manager Service + participant File Operator as File Operator + participant Resource Plugin as Resource Plugin + participant Resource Service as Resource Service + participant Instance Operator as Instance Operator + participant Log Tailer Operator as Log Tailer Operator - Message Bus -)+ File Plugin: ConfigApplyFailedTopic - File Plugin ->>+ File Manager Service: Rollback(ctx, instanceID) - File Manager Service ->> File Operator: Write() - File Operator -->> File Manager Service: error - File Manager Service -->>- File Plugin: error - alt error - rect rgb(166, 128, 140) - File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_ERROR - File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE - Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_ERROR - Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE + Message Bus -)+ File Plugin: ConfigApplyFailedTopic + File Plugin ->>+ File Manager Service: Rollback(ctx, instanceID) + File Manager Service ->> File Operator: Write() + File Operator -->> File Manager Service: error + File Manager Service -->>- File Plugin: error + alt error + rect rgb(166, 128, 140) + File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_ERROR + Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_ERROR + File Plugin -) Message Bus: ConfigApplyCompleteTopic + Message Bus -) Watcher Plugin: ConfigApplyCompleteTopic + Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) + Message Bus -) File Plugin: ConfigApplyCompleteTopic + File Plugin ->> File Plugin: ClearCache() + File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE + Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE + end + else no error + rect rgb(66, 129, 164) + File Plugin -)- Message Bus: RollbackWriteTopic + end end - else no error - rect rgb(66, 129, 164) - File Plugin -)- Message Bus: RollbackWriteTopic + Message Bus -)+ Resource Plugin: WriteConfigSuccessfulTopic + Resource Plugin ->>+ Resource Service: ApplyConfig(ctx, instanceID) + Resource Service ->>+ Instance Operator: Validate(ctx, instance) + Instance Operator ->> Instance Operator: validateConfigCheckResponse() + Instance Operator -->>- Resource Service: error + Resource Service ->>+ Instance Operator: Reload(ctx, instance) + loop monitorLogs() + Instance Operator ->>+ Log Tailer Operator: Tail(ctx, errorLog, errorChannel) + loop Tail() + Log Tailer Operator ->>- Log Tailer Operator: doesLogLineContainError(line) + Log Tailer Operator -->> Instance Operator: error + end end - end - Message Bus -)+ Resource Plugin: WriteConfigSuccessfulTopic - Resource Plugin ->>+ Resource Service: ApplyConfig(ctx, instanceID) - Resource Service ->>+ Instance Operator: Validate(ctx, instance) - Instance Operator ->> Instance Operator: validateConfigCheckResponse() - Instance Operator -->>- Resource Service: error - Resource Service ->>+ Instance Operator: Reload(ctx, instance) - loop monitorLogs() - Instance Operator ->>+ Log Tailer Operator: Tail(ctx, errorLog, errorChannel) - loop Tail() - Log Tailer Operator ->>- Log Tailer Operator: doesLogLineContainError(line) - Log Tailer Operator -->> Instance Operator: error - end - end - Instance Operator -->>- Resource Service: error - Resource Service -->>- Resource Plugin: error - alt no error - rect rgb(66, 129, 164) - Resource Plugin -) Message Bus: RollbackCompleteTopic - Resource Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE - Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE - Message Bus -)+ File Plugin: RollbackCompleteTopic - File Plugin ->>- File Plugin: clearCache() - end - else error - rect rgb(166, 128, 140) - Resource Plugin -) Message Bus: RollbackCompleteTopic - Resource Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_ERROR - Resource Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE - Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_ERROR - Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE - Message Bus -)+ File Plugin: RollbackCompleteTopic - File Plugin ->>- File Plugin: clearCache() + Instance Operator -->>- Resource Service: error + Resource Service -->>- Resource Plugin: error + alt no error + rect rgb(66, 129, 164) + Resource Plugin -) Message Bus: ConfigApplyCompleteTopic + Message Bus -) Watcher Plugin: ConfigApplyCompleteTopic + Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) + Message Bus -)+ File Plugin: ConfigApplyCompleteTopic + File Plugin ->>- File Plugin: clearCache() + File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE + Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE + end + else error + rect rgb(166, 128, 140) + Resource Plugin -) Message Bus: ConfigApplyCompleteTopic + Message Bus -) Watcher Plugin: ConfigApplyCompleteTopic + Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) + Resource Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_ERROR + Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_ERROR + Message Bus -)+ File Plugin: ConfigApplyCompleteTopic + File Plugin ->> File Plugin: clearCache() + File Plugin -)- Message Bus: DataPlaneResponseTopic Command_Status_FAILURE + Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE + + end end - end + ``` From 946a5cfa567308a5185ccd650c5077a74c3f0053 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Fri, 25 Oct 2024 17:03:11 +0100 Subject: [PATCH 11/12] update rollback diagrams --- docs/architecture/config_apply_rollback.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/config_apply_rollback.md b/docs/architecture/config_apply_rollback.md index 1d56542b26..7ae2b4c9bb 100644 --- a/docs/architecture/config_apply_rollback.md +++ b/docs/architecture/config_apply_rollback.md @@ -78,8 +78,8 @@ sequenceDiagram Message Bus -) Watcher Plugin: ConfigApplyCompleteTopic Watcher Plugin ->> Watcher Plugin: FileWatcherService.SetEnabled(true) Message Bus -)+ File Plugin: ConfigApplyCompleteTopic - File Plugin ->>- File Plugin: clearCache() - File Plugin -) Message Bus: DataPlaneResponseTopic Command_Status_FAILURE + File Plugin ->> File Plugin: clearCache() + File Plugin -)- Message Bus: DataPlaneResponseTopic Command_Status_FAILURE Message Bus -) Command Plugin: DataPlaneResponseTopic Command_Status_FAILURE end else error From 48a054c4e20ebec965254b19e76431dc741c3387 Mon Sep 17 00:00:00 2001 From: Aphral Griffin Date: Tue, 5 Nov 2024 10:24:14 +0000 Subject: [PATCH 12/12] PR feedback --- internal/file/file_manager_service.go | 2 +- internal/watcher/watcher_plugin.go | 4 ++-- test/integration/grpc_management_plane_api_test.go | 4 ++-- test/mock/grpc/mock_management_command_service.go | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/file/file_manager_service.go b/internal/file/file_manager_service.go index 04b2611d65..149d0ce64f 100644 --- a/internal/file/file_manager_service.go +++ b/internal/file/file_manager_service.go @@ -426,7 +426,7 @@ func (fms *FileManagerService) DetermineFileActions(currentFiles, modifiedFiles } else if file.GetFileMeta().GetHash() != currentFile.GetFileMeta().GetHash() { fileContent, readErr := os.ReadFile(fileName) if readErr != nil { - return nil, nil, fmt.Errorf("error generating hash for file %s, error: %w", fileName, readErr) + return nil, nil, fmt.Errorf("error reading file %s, error: %w", fileName, readErr) } file.Action = &updateAction fileContents[fileName] = fileContent diff --git a/internal/watcher/watcher_plugin.go b/internal/watcher/watcher_plugin.go index 897d248fb6..f49db08b80 100644 --- a/internal/watcher/watcher_plugin.go +++ b/internal/watcher/watcher_plugin.go @@ -112,7 +112,7 @@ func (w *Watcher) Process(ctx context.Context, msg *bus.Message) { case bus.ConfigApplySuccessfulTopic: w.handleConfigApplySuccess(ctx, msg) case bus.ConfigApplyCompleteTopic: - w.handleRollbackComplete(ctx, msg) + w.handleConfigApplyComplete(ctx, msg) default: slog.DebugContext(ctx, "Watcher plugin unknown topic", "topic", msg.Topic) } @@ -171,7 +171,7 @@ func (w *Watcher) handleConfigApplySuccess(ctx context.Context, msg *bus.Message w.instanceWatcherService.ReparseConfig(ctx, instanceID) } -func (w *Watcher) handleRollbackComplete(ctx context.Context, msg *bus.Message) { +func (w *Watcher) handleConfigApplyComplete(ctx context.Context, msg *bus.Message) { response, ok := msg.Data.(*mpi.DataPlaneResponse) if !ok { slog.ErrorContext(ctx, "Unable to cast message payload to *mpi.DataPlaneResponse", "payload", diff --git a/test/integration/grpc_management_plane_api_test.go b/test/integration/grpc_management_plane_api_test.go index 7e5427915e..3b20cc9bcf 100644 --- a/test/integration/grpc_management_plane_api_test.go +++ b/test/integration/grpc_management_plane_api_test.go @@ -450,8 +450,8 @@ func clearManagementPlaneResponses(t *testing.T) { client := resty.New() - url := fmt.Sprintf("http://%s/api/v1/responses/delete", mockManagementPlaneAPIAddress) - resp, err := client.R().EnableTrace().Get(url) + url := fmt.Sprintf("http://%s/api/v1/responses", mockManagementPlaneAPIAddress) + resp, err := client.R().EnableTrace().Delete(url) require.NoError(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode()) diff --git a/test/mock/grpc/mock_management_command_service.go b/test/mock/grpc/mock_management_command_service.go index bc1c9db8cf..9fa4cdf2cf 100644 --- a/test/mock/grpc/mock_management_command_service.go +++ b/test/mock/grpc/mock_management_command_service.go @@ -312,7 +312,7 @@ func (cs *CommandService) addResponseAndRequestEndpoints() { } }) - cs.server.GET("/api/v1/responses/delete", func(c *gin.Context) { + cs.server.DELETE("/api/v1/responses", func(c *gin.Context) { cs.dataPlaneResponsesMutex.Lock() defer cs.dataPlaneResponsesMutex.Unlock()