diff --git a/api/grpc/mpi/v1/command.pb.go b/api/grpc/mpi/v1/command.pb.go index cc7be11bc..6b7bf1d7c 100644 --- a/api/grpc/mpi/v1/command.pb.go +++ b/api/grpc/mpi/v1/command.pb.go @@ -102,6 +102,8 @@ const ( InstanceMeta_INSTANCE_TYPE_NGINX_PLUS InstanceMeta_InstanceType = 3 // NGINX Unit InstanceMeta_INSTANCE_TYPE_UNIT InstanceMeta_InstanceType = 4 + // NGINX App Protect + InstanceMeta_INSTANCE_TYPE_NGINX_APP_PROTECT InstanceMeta_InstanceType = 5 ) // Enum value maps for InstanceMeta_InstanceType. @@ -112,13 +114,15 @@ var ( 2: "INSTANCE_TYPE_NGINX", 3: "INSTANCE_TYPE_NGINX_PLUS", 4: "INSTANCE_TYPE_UNIT", + 5: "INSTANCE_TYPE_NGINX_APP_PROTECT", } InstanceMeta_InstanceType_value = map[string]int32{ - "INSTANCE_TYPE_UNSPECIFIED": 0, - "INSTANCE_TYPE_AGENT": 1, - "INSTANCE_TYPE_NGINX": 2, - "INSTANCE_TYPE_NGINX_PLUS": 3, - "INSTANCE_TYPE_UNIT": 4, + "INSTANCE_TYPE_UNSPECIFIED": 0, + "INSTANCE_TYPE_AGENT": 1, + "INSTANCE_TYPE_NGINX": 2, + "INSTANCE_TYPE_NGINX_PLUS": 3, + "INSTANCE_TYPE_UNIT": 4, + "INSTANCE_TYPE_NGINX_APP_PROTECT": 5, } ) @@ -1910,6 +1914,7 @@ type InstanceRuntime struct { // // *InstanceRuntime_NginxRuntimeInfo // *InstanceRuntime_NginxPlusRuntimeInfo + // *InstanceRuntime_NginxAppProtectRuntimeInfo Details isInstanceRuntime_Details `protobuf_oneof:"details"` // List of worker processes InstanceChildren []*InstanceChild `protobuf:"bytes,6,rep,name=instance_children,json=instanceChildren,proto3" json:"instance_children,omitempty"` @@ -1993,6 +1998,15 @@ func (x *InstanceRuntime) GetNginxPlusRuntimeInfo() *NGINXPlusRuntimeInfo { return nil } +func (x *InstanceRuntime) GetNginxAppProtectRuntimeInfo() *NGINXAppProtectRuntimeInfo { + if x != nil { + if x, ok := x.Details.(*InstanceRuntime_NginxAppProtectRuntimeInfo); ok { + return x.NginxAppProtectRuntimeInfo + } + } + return nil +} + func (x *InstanceRuntime) GetInstanceChildren() []*InstanceChild { if x != nil { return x.InstanceChildren @@ -2014,10 +2028,17 @@ type InstanceRuntime_NginxPlusRuntimeInfo struct { NginxPlusRuntimeInfo *NGINXPlusRuntimeInfo `protobuf:"bytes,5,opt,name=nginx_plus_runtime_info,json=nginxPlusRuntimeInfo,proto3,oneof"` } +type InstanceRuntime_NginxAppProtectRuntimeInfo struct { + // NGINX App Protect runtime information + NginxAppProtectRuntimeInfo *NGINXAppProtectRuntimeInfo `protobuf:"bytes,7,opt,name=nginx_app_protect_runtime_info,json=nginxAppProtectRuntimeInfo,proto3,oneof"` +} + func (*InstanceRuntime_NginxRuntimeInfo) isInstanceRuntime_Details() {} func (*InstanceRuntime_NginxPlusRuntimeInfo) isInstanceRuntime_Details() {} +func (*InstanceRuntime_NginxAppProtectRuntimeInfo) isInstanceRuntime_Details() {} + type InstanceChild struct { state protoimpl.MessageState `protogen:"open.v1"` // the process identifier @@ -2290,6 +2311,70 @@ func (x *APIDetails) GetListen() string { return "" } +// A set of runtime NGINX App Protect settings +type NGINXAppProtectRuntimeInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + // NGINX App Protect Release + Release string `protobuf:"bytes,1,opt,name=release,proto3" json:"release,omitempty"` + // Attack signature version + AttackSignatureVersion string `protobuf:"bytes,2,opt,name=attack_signature_version,json=attackSignatureVersion,proto3" json:"attack_signature_version,omitempty"` + // Threat campaign version + ThreatCampaignVersion string `protobuf:"bytes,3,opt,name=threat_campaign_version,json=threatCampaignVersion,proto3" json:"threat_campaign_version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NGINXAppProtectRuntimeInfo) Reset() { + *x = NGINXAppProtectRuntimeInfo{} + mi := &file_mpi_v1_command_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NGINXAppProtectRuntimeInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NGINXAppProtectRuntimeInfo) ProtoMessage() {} + +func (x *NGINXAppProtectRuntimeInfo) ProtoReflect() protoreflect.Message { + mi := &file_mpi_v1_command_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NGINXAppProtectRuntimeInfo.ProtoReflect.Descriptor instead. +func (*NGINXAppProtectRuntimeInfo) Descriptor() ([]byte, []int) { + return file_mpi_v1_command_proto_rawDescGZIP(), []int{33} +} + +func (x *NGINXAppProtectRuntimeInfo) GetRelease() string { + if x != nil { + return x.Release + } + return "" +} + +func (x *NGINXAppProtectRuntimeInfo) GetAttackSignatureVersion() string { + if x != nil { + return x.AttackSignatureVersion + } + return "" +} + +func (x *NGINXAppProtectRuntimeInfo) GetThreatCampaignVersion() string { + if x != nil { + return x.ThreatCampaignVersion + } + return "" +} + // A set of actions that can be performed on an instance type InstanceAction struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -2299,7 +2384,7 @@ type InstanceAction struct { func (x *InstanceAction) Reset() { *x = InstanceAction{} - mi := &file_mpi_v1_command_proto_msgTypes[33] + mi := &file_mpi_v1_command_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2311,7 +2396,7 @@ func (x *InstanceAction) String() string { func (*InstanceAction) ProtoMessage() {} func (x *InstanceAction) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[33] + mi := &file_mpi_v1_command_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2324,7 +2409,7 @@ func (x *InstanceAction) ProtoReflect() protoreflect.Message { // Deprecated: Use InstanceAction.ProtoReflect.Descriptor instead. func (*InstanceAction) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{33} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{34} } // This contains a series of NGINX Agent configurations @@ -2348,7 +2433,7 @@ type AgentConfig struct { func (x *AgentConfig) Reset() { *x = AgentConfig{} - mi := &file_mpi_v1_command_proto_msgTypes[34] + mi := &file_mpi_v1_command_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2360,7 +2445,7 @@ func (x *AgentConfig) String() string { func (*AgentConfig) ProtoMessage() {} func (x *AgentConfig) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[34] + mi := &file_mpi_v1_command_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2373,7 +2458,7 @@ func (x *AgentConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentConfig.ProtoReflect.Descriptor instead. func (*AgentConfig) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{34} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{35} } func (x *AgentConfig) GetCommand() *CommandServer { @@ -2433,7 +2518,7 @@ type CommandServer struct { func (x *CommandServer) Reset() { *x = CommandServer{} - mi := &file_mpi_v1_command_proto_msgTypes[35] + mi := &file_mpi_v1_command_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2445,7 +2530,7 @@ func (x *CommandServer) String() string { func (*CommandServer) ProtoMessage() {} func (x *CommandServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[35] + mi := &file_mpi_v1_command_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2458,7 +2543,7 @@ func (x *CommandServer) ProtoReflect() protoreflect.Message { // Deprecated: Use CommandServer.ProtoReflect.Descriptor instead. func (*CommandServer) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{35} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{36} } func (x *CommandServer) GetServer() *ServerSettings { @@ -2491,7 +2576,7 @@ type MetricsServer struct { func (x *MetricsServer) Reset() { *x = MetricsServer{} - mi := &file_mpi_v1_command_proto_msgTypes[36] + mi := &file_mpi_v1_command_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2503,7 +2588,7 @@ func (x *MetricsServer) String() string { func (*MetricsServer) ProtoMessage() {} func (x *MetricsServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[36] + mi := &file_mpi_v1_command_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2516,7 +2601,7 @@ func (x *MetricsServer) ProtoReflect() protoreflect.Message { // Deprecated: Use MetricsServer.ProtoReflect.Descriptor instead. func (*MetricsServer) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{36} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{37} } // The file settings associated with file server for configurations @@ -2528,7 +2613,7 @@ type FileServer struct { func (x *FileServer) Reset() { *x = FileServer{} - mi := &file_mpi_v1_command_proto_msgTypes[37] + mi := &file_mpi_v1_command_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2540,7 +2625,7 @@ func (x *FileServer) String() string { func (*FileServer) ProtoMessage() {} func (x *FileServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[37] + mi := &file_mpi_v1_command_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2553,7 +2638,7 @@ func (x *FileServer) ProtoReflect() protoreflect.Message { // Deprecated: Use FileServer.ProtoReflect.Descriptor instead. func (*FileServer) Descriptor() ([]byte, []int) { - return file_mpi_v1_command_proto_rawDescGZIP(), []int{37} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{38} } var File_mpi_v1_command_proto protoreflect.FileDescriptor @@ -2800,7 +2885,7 @@ var file_mpi_v1_command_proto_rawDesc = string([]byte{ 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x22, - 0xb3, 0x02, 0x0a, 0x0c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0xd8, 0x02, 0x0a, 0x0c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x29, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x46, 0x0a, 0x0d, 0x69, @@ -2809,7 +2894,7 @@ var file_mpi_v1_command_proto_rawDesc = string([]byte{ 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x95, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xba, 0x01, 0x0a, 0x0c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, @@ -2819,132 +2904,152 @@ var file_mpi_v1_command_proto_rawDesc = string([]byte{ 0x1c, 0x0a, 0x18, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, - 0x4e, 0x49, 0x54, 0x10, 0x04, 0x22, 0x86, 0x01, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x0a, 0x0c, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xf6, - 0x02, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, - 0x64, 0x12, 0x29, 0x0a, 0x0b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x3a, 0x01, 0x2f, - 0x52, 0x0a, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x29, 0x0a, 0x0b, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0x3a, 0x01, 0x2f, 0x52, 0x0a, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x48, 0x0a, 0x12, 0x6e, 0x67, 0x69, 0x6e, 0x78, - 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x47, 0x49, - 0x4e, 0x58, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, - 0x10, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x55, 0x0a, 0x17, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x47, 0x49, 0x4e, - 0x58, 0x50, 0x6c, 0x75, 0x73, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x48, 0x00, 0x52, 0x14, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x50, 0x6c, 0x75, 0x73, 0x52, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x42, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x06, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x10, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x42, 0x09, 0x0a, 0x07, - 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x2e, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x22, 0xdb, 0x01, 0x0a, 0x10, 0x4e, 0x47, 0x49, 0x4e, - 0x58, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0b, - 0x73, 0x74, 0x75, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x75, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, - 0x67, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x6f, 0x67, - 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x6f, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x6f, 0x61, - 0x64, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, - 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x8e, 0x02, 0x0a, 0x14, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x50, - 0x6c, 0x75, 0x73, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, - 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, - 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x75, 0x62, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, - 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, - 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4c, - 0x6f, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x6f, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6c, - 0x6f, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x27, - 0x0a, 0x0f, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, - 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x5f, - 0x61, 0x70, 0x69, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x07, 0x70, - 0x6c, 0x75, 0x73, 0x41, 0x70, 0x69, 0x22, 0x40, 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x22, 0x10, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x02, 0x0a, 0x0b, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x07, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, - 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x0a, 0x04, - 0x66, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x04, - 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x75, 0x66, - 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, - 0x65, 0x22, 0x90, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x53, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, 0x25, 0x0a, - 0x03, 0x74, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x4c, 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, - 0x03, 0x74, 0x6c, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x0c, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x32, 0x87, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x6d, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x70, + 0x4e, 0x49, 0x54, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x5f, 0x41, 0x50, 0x50, + 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, 0x10, 0x05, 0x22, 0x86, 0x01, 0x0a, 0x0e, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, + 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x38, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x22, 0xe7, 0x03, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x0b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x72, 0x03, 0x3a, 0x01, 0x2f, 0x52, 0x0a, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x30, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0f, 0xba, 0x48, 0x0c, 0x72, 0x0a, 0x32, 0x08, 0x5e, + 0x5c, 0x2f, 0x2e, 0x2a, 0x7c, 0x5e, 0x24, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, + 0x61, 0x74, 0x68, 0x12, 0x48, 0x0a, 0x12, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x5f, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x10, 0x6e, 0x67, 0x69, + 0x6e, 0x78, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x55, 0x0a, + 0x17, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x5f, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x50, 0x6c, 0x75, + 0x73, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x14, + 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x50, 0x6c, 0x75, 0x73, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x68, 0x0a, 0x1e, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x5f, 0x61, 0x70, + 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x41, 0x70, 0x70, 0x50, 0x72, + 0x6f, 0x74, 0x65, 0x63, 0x74, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x48, 0x00, 0x52, 0x1a, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x41, 0x70, 0x70, 0x50, 0x72, 0x6f, 0x74, + 0x65, 0x63, 0x74, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x42, + 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, + 0x52, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, + 0x65, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x2e, 0x0a, + 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x22, 0xdb, 0x01, + 0x0a, 0x10, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x2e, 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0a, 0x73, 0x74, 0x75, + 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x6f, 0x61, 0x64, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0f, 0x6c, 0x6f, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x79, 0x6e, + 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x8e, 0x02, 0x0a, 0x14, + 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x50, 0x6c, 0x75, 0x73, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0a, 0x73, + 0x74, 0x75, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x6f, 0x61, + 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x6f, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2d, 0x0a, + 0x08, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x61, 0x70, 0x69, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x52, 0x07, 0x70, 0x6c, 0x75, 0x73, 0x41, 0x70, 0x69, 0x22, 0x40, 0x0a, 0x0a, + 0x41, 0x50, 0x49, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x22, 0xa8, + 0x01, 0x0a, 0x1a, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x41, 0x70, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, + 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x61, 0x74, 0x74, 0x61, 0x63, + 0x6b, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x61, 0x74, 0x74, 0x61, 0x63, + 0x6b, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x5f, 0x63, 0x61, 0x6d, 0x70, + 0x61, 0x69, 0x67, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x15, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x43, 0x61, 0x6d, 0x70, 0x61, 0x69, + 0x67, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x10, 0x0a, 0x0e, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x02, 0x0a, 0x0b, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2f, 0x0a, 0x07, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2f, 0x0a, 0x07, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x0a, + 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, + 0x7a, 0x65, 0x22, 0x90, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x12, 0x25, + 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x4c, 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x52, 0x03, 0x74, 0x6c, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x0c, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x32, 0x87, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x66, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, - 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, - 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, - 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x66, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, + 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, + 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x66, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x12, 0x24, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x12, 0x24, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x4c, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x19, 0x2e, 0x6d, - 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1e, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x6e, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, 0x5a, - 0x06, 0x6d, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x4c, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x19, 0x2e, + 0x6d, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6c, 0x61, 0x6e, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x1e, 0x2e, 0x6d, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6c, 0x61, 0x6e, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x08, + 0x5a, 0x06, 0x6d, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( @@ -2960,7 +3065,7 @@ func file_mpi_v1_command_proto_rawDescGZIP() []byte { } var file_mpi_v1_command_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_mpi_v1_command_proto_msgTypes = make([]protoimpl.MessageInfo, 38) +var file_mpi_v1_command_proto_msgTypes = make([]protoimpl.MessageInfo, 39) var file_mpi_v1_command_proto_goTypes = []any{ (InstanceHealth_InstanceHealthStatus)(0), // 0: mpi.v1.InstanceHealth.InstanceHealthStatus (InstanceMeta_InstanceType)(0), // 1: mpi.v1.InstanceMeta.InstanceType @@ -2997,85 +3102,87 @@ var file_mpi_v1_command_proto_goTypes = []any{ (*NGINXRuntimeInfo)(nil), // 32: mpi.v1.NGINXRuntimeInfo (*NGINXPlusRuntimeInfo)(nil), // 33: mpi.v1.NGINXPlusRuntimeInfo (*APIDetails)(nil), // 34: mpi.v1.APIDetails - (*InstanceAction)(nil), // 35: mpi.v1.InstanceAction - (*AgentConfig)(nil), // 36: mpi.v1.AgentConfig - (*CommandServer)(nil), // 37: mpi.v1.CommandServer - (*MetricsServer)(nil), // 38: mpi.v1.MetricsServer - (*FileServer)(nil), // 39: mpi.v1.FileServer - (*MessageMeta)(nil), // 40: mpi.v1.MessageMeta - (*CommandResponse)(nil), // 41: mpi.v1.CommandResponse - (*FileOverview)(nil), // 42: mpi.v1.FileOverview - (*structpb.Struct)(nil), // 43: google.protobuf.Struct - (*ServerSettings)(nil), // 44: mpi.v1.ServerSettings - (*AuthSettings)(nil), // 45: mpi.v1.AuthSettings - (*TLSSettings)(nil), // 46: mpi.v1.TLSSettings + (*NGINXAppProtectRuntimeInfo)(nil), // 35: mpi.v1.NGINXAppProtectRuntimeInfo + (*InstanceAction)(nil), // 36: mpi.v1.InstanceAction + (*AgentConfig)(nil), // 37: mpi.v1.AgentConfig + (*CommandServer)(nil), // 38: mpi.v1.CommandServer + (*MetricsServer)(nil), // 39: mpi.v1.MetricsServer + (*FileServer)(nil), // 40: mpi.v1.FileServer + (*MessageMeta)(nil), // 41: mpi.v1.MessageMeta + (*CommandResponse)(nil), // 42: mpi.v1.CommandResponse + (*FileOverview)(nil), // 43: mpi.v1.FileOverview + (*structpb.Struct)(nil), // 44: google.protobuf.Struct + (*ServerSettings)(nil), // 45: mpi.v1.ServerSettings + (*AuthSettings)(nil), // 46: mpi.v1.AuthSettings + (*TLSSettings)(nil), // 47: mpi.v1.TLSSettings } var file_mpi_v1_command_proto_depIdxs = []int32{ - 40, // 0: mpi.v1.CreateConnectionRequest.message_meta:type_name -> mpi.v1.MessageMeta + 41, // 0: mpi.v1.CreateConnectionRequest.message_meta:type_name -> mpi.v1.MessageMeta 3, // 1: mpi.v1.CreateConnectionRequest.resource:type_name -> mpi.v1.Resource 27, // 2: mpi.v1.Resource.instances:type_name -> mpi.v1.Instance 4, // 3: mpi.v1.Resource.host_info:type_name -> mpi.v1.HostInfo 6, // 4: mpi.v1.Resource.container_info:type_name -> mpi.v1.ContainerInfo 5, // 5: mpi.v1.HostInfo.release_info:type_name -> mpi.v1.ReleaseInfo 5, // 6: mpi.v1.ContainerInfo.release_info:type_name -> mpi.v1.ReleaseInfo - 41, // 7: mpi.v1.CreateConnectionResponse.response:type_name -> mpi.v1.CommandResponse - 36, // 8: mpi.v1.CreateConnectionResponse.agent_config:type_name -> mpi.v1.AgentConfig - 40, // 9: mpi.v1.UpdateDataPlaneStatusRequest.message_meta:type_name -> mpi.v1.MessageMeta + 42, // 7: mpi.v1.CreateConnectionResponse.response:type_name -> mpi.v1.CommandResponse + 37, // 8: mpi.v1.CreateConnectionResponse.agent_config:type_name -> mpi.v1.AgentConfig + 41, // 9: mpi.v1.UpdateDataPlaneStatusRequest.message_meta:type_name -> mpi.v1.MessageMeta 3, // 10: mpi.v1.UpdateDataPlaneStatusRequest.resource:type_name -> mpi.v1.Resource 0, // 11: mpi.v1.InstanceHealth.instance_health_status:type_name -> mpi.v1.InstanceHealth.InstanceHealthStatus - 40, // 12: mpi.v1.UpdateDataPlaneHealthRequest.message_meta:type_name -> mpi.v1.MessageMeta + 41, // 12: mpi.v1.UpdateDataPlaneHealthRequest.message_meta:type_name -> mpi.v1.MessageMeta 10, // 13: mpi.v1.UpdateDataPlaneHealthRequest.instance_healths:type_name -> mpi.v1.InstanceHealth - 40, // 14: mpi.v1.DataPlaneResponse.message_meta:type_name -> mpi.v1.MessageMeta - 41, // 15: mpi.v1.DataPlaneResponse.command_response:type_name -> mpi.v1.CommandResponse - 40, // 16: mpi.v1.ManagementPlaneRequest.message_meta:type_name -> mpi.v1.MessageMeta + 41, // 14: mpi.v1.DataPlaneResponse.message_meta:type_name -> mpi.v1.MessageMeta + 42, // 15: mpi.v1.DataPlaneResponse.command_response:type_name -> mpi.v1.CommandResponse + 41, // 16: mpi.v1.ManagementPlaneRequest.message_meta:type_name -> mpi.v1.MessageMeta 15, // 17: mpi.v1.ManagementPlaneRequest.status_request:type_name -> mpi.v1.StatusRequest 16, // 18: mpi.v1.ManagementPlaneRequest.health_request:type_name -> mpi.v1.HealthRequest 17, // 19: mpi.v1.ManagementPlaneRequest.config_apply_request:type_name -> mpi.v1.ConfigApplyRequest 18, // 20: mpi.v1.ManagementPlaneRequest.config_upload_request:type_name -> mpi.v1.ConfigUploadRequest 19, // 21: mpi.v1.ManagementPlaneRequest.action_request:type_name -> mpi.v1.APIActionRequest 26, // 22: mpi.v1.ManagementPlaneRequest.command_status_request:type_name -> mpi.v1.CommandStatusRequest - 42, // 23: mpi.v1.ConfigApplyRequest.overview:type_name -> mpi.v1.FileOverview - 42, // 24: mpi.v1.ConfigUploadRequest.overview:type_name -> mpi.v1.FileOverview + 43, // 23: mpi.v1.ConfigApplyRequest.overview:type_name -> mpi.v1.FileOverview + 43, // 24: mpi.v1.ConfigUploadRequest.overview:type_name -> mpi.v1.FileOverview 20, // 25: mpi.v1.APIActionRequest.nginx_plus_action:type_name -> mpi.v1.NGINXPlusAction 21, // 26: mpi.v1.NGINXPlusAction.update_http_upstream_servers:type_name -> mpi.v1.UpdateHTTPUpstreamServers 22, // 27: mpi.v1.NGINXPlusAction.get_http_upstream_servers:type_name -> mpi.v1.GetHTTPUpstreamServers 23, // 28: mpi.v1.NGINXPlusAction.update_stream_servers:type_name -> mpi.v1.UpdateStreamServers 24, // 29: mpi.v1.NGINXPlusAction.get_upstreams:type_name -> mpi.v1.GetUpstreams 25, // 30: mpi.v1.NGINXPlusAction.get_stream_upstreams:type_name -> mpi.v1.GetStreamUpstreams - 43, // 31: mpi.v1.UpdateHTTPUpstreamServers.servers:type_name -> google.protobuf.Struct - 43, // 32: mpi.v1.UpdateStreamServers.servers:type_name -> google.protobuf.Struct + 44, // 31: mpi.v1.UpdateHTTPUpstreamServers.servers:type_name -> google.protobuf.Struct + 44, // 32: mpi.v1.UpdateStreamServers.servers:type_name -> google.protobuf.Struct 28, // 33: mpi.v1.Instance.instance_meta:type_name -> mpi.v1.InstanceMeta 29, // 34: mpi.v1.Instance.instance_config:type_name -> mpi.v1.InstanceConfig 30, // 35: mpi.v1.Instance.instance_runtime:type_name -> mpi.v1.InstanceRuntime 1, // 36: mpi.v1.InstanceMeta.instance_type:type_name -> mpi.v1.InstanceMeta.InstanceType - 35, // 37: mpi.v1.InstanceConfig.actions:type_name -> mpi.v1.InstanceAction - 36, // 38: mpi.v1.InstanceConfig.agent_config:type_name -> mpi.v1.AgentConfig + 36, // 37: mpi.v1.InstanceConfig.actions:type_name -> mpi.v1.InstanceAction + 37, // 38: mpi.v1.InstanceConfig.agent_config:type_name -> mpi.v1.AgentConfig 32, // 39: mpi.v1.InstanceRuntime.nginx_runtime_info:type_name -> mpi.v1.NGINXRuntimeInfo 33, // 40: mpi.v1.InstanceRuntime.nginx_plus_runtime_info:type_name -> mpi.v1.NGINXPlusRuntimeInfo - 31, // 41: mpi.v1.InstanceRuntime.instance_children:type_name -> mpi.v1.InstanceChild - 34, // 42: mpi.v1.NGINXRuntimeInfo.stub_status:type_name -> mpi.v1.APIDetails - 34, // 43: mpi.v1.NGINXPlusRuntimeInfo.stub_status:type_name -> mpi.v1.APIDetails - 34, // 44: mpi.v1.NGINXPlusRuntimeInfo.plus_api:type_name -> mpi.v1.APIDetails - 37, // 45: mpi.v1.AgentConfig.command:type_name -> mpi.v1.CommandServer - 38, // 46: mpi.v1.AgentConfig.metrics:type_name -> mpi.v1.MetricsServer - 39, // 47: mpi.v1.AgentConfig.file:type_name -> mpi.v1.FileServer - 43, // 48: mpi.v1.AgentConfig.labels:type_name -> google.protobuf.Struct - 44, // 49: mpi.v1.CommandServer.server:type_name -> mpi.v1.ServerSettings - 45, // 50: mpi.v1.CommandServer.auth:type_name -> mpi.v1.AuthSettings - 46, // 51: mpi.v1.CommandServer.tls:type_name -> mpi.v1.TLSSettings - 2, // 52: mpi.v1.CommandService.CreateConnection:input_type -> mpi.v1.CreateConnectionRequest - 8, // 53: mpi.v1.CommandService.UpdateDataPlaneStatus:input_type -> mpi.v1.UpdateDataPlaneStatusRequest - 11, // 54: mpi.v1.CommandService.UpdateDataPlaneHealth:input_type -> mpi.v1.UpdateDataPlaneHealthRequest - 13, // 55: mpi.v1.CommandService.Subscribe:input_type -> mpi.v1.DataPlaneResponse - 7, // 56: mpi.v1.CommandService.CreateConnection:output_type -> mpi.v1.CreateConnectionResponse - 9, // 57: mpi.v1.CommandService.UpdateDataPlaneStatus:output_type -> mpi.v1.UpdateDataPlaneStatusResponse - 12, // 58: mpi.v1.CommandService.UpdateDataPlaneHealth:output_type -> mpi.v1.UpdateDataPlaneHealthResponse - 14, // 59: mpi.v1.CommandService.Subscribe:output_type -> mpi.v1.ManagementPlaneRequest - 56, // [56:60] is the sub-list for method output_type - 52, // [52:56] is the sub-list for method input_type - 52, // [52:52] is the sub-list for extension type_name - 52, // [52:52] is the sub-list for extension extendee - 0, // [0:52] is the sub-list for field type_name + 35, // 41: mpi.v1.InstanceRuntime.nginx_app_protect_runtime_info:type_name -> mpi.v1.NGINXAppProtectRuntimeInfo + 31, // 42: mpi.v1.InstanceRuntime.instance_children:type_name -> mpi.v1.InstanceChild + 34, // 43: mpi.v1.NGINXRuntimeInfo.stub_status:type_name -> mpi.v1.APIDetails + 34, // 44: mpi.v1.NGINXPlusRuntimeInfo.stub_status:type_name -> mpi.v1.APIDetails + 34, // 45: mpi.v1.NGINXPlusRuntimeInfo.plus_api:type_name -> mpi.v1.APIDetails + 38, // 46: mpi.v1.AgentConfig.command:type_name -> mpi.v1.CommandServer + 39, // 47: mpi.v1.AgentConfig.metrics:type_name -> mpi.v1.MetricsServer + 40, // 48: mpi.v1.AgentConfig.file:type_name -> mpi.v1.FileServer + 44, // 49: mpi.v1.AgentConfig.labels:type_name -> google.protobuf.Struct + 45, // 50: mpi.v1.CommandServer.server:type_name -> mpi.v1.ServerSettings + 46, // 51: mpi.v1.CommandServer.auth:type_name -> mpi.v1.AuthSettings + 47, // 52: mpi.v1.CommandServer.tls:type_name -> mpi.v1.TLSSettings + 2, // 53: mpi.v1.CommandService.CreateConnection:input_type -> mpi.v1.CreateConnectionRequest + 8, // 54: mpi.v1.CommandService.UpdateDataPlaneStatus:input_type -> mpi.v1.UpdateDataPlaneStatusRequest + 11, // 55: mpi.v1.CommandService.UpdateDataPlaneHealth:input_type -> mpi.v1.UpdateDataPlaneHealthRequest + 13, // 56: mpi.v1.CommandService.Subscribe:input_type -> mpi.v1.DataPlaneResponse + 7, // 57: mpi.v1.CommandService.CreateConnection:output_type -> mpi.v1.CreateConnectionResponse + 9, // 58: mpi.v1.CommandService.UpdateDataPlaneStatus:output_type -> mpi.v1.UpdateDataPlaneStatusResponse + 12, // 59: mpi.v1.CommandService.UpdateDataPlaneHealth:output_type -> mpi.v1.UpdateDataPlaneHealthResponse + 14, // 60: mpi.v1.CommandService.Subscribe:output_type -> mpi.v1.ManagementPlaneRequest + 57, // [57:61] is the sub-list for method output_type + 53, // [53:57] is the sub-list for method input_type + 53, // [53:53] is the sub-list for extension type_name + 53, // [53:53] is the sub-list for extension extendee + 0, // [0:53] is the sub-list for field type_name } func init() { file_mpi_v1_command_proto_init() } @@ -3113,6 +3220,7 @@ func file_mpi_v1_command_proto_init() { file_mpi_v1_command_proto_msgTypes[28].OneofWrappers = []any{ (*InstanceRuntime_NginxRuntimeInfo)(nil), (*InstanceRuntime_NginxPlusRuntimeInfo)(nil), + (*InstanceRuntime_NginxAppProtectRuntimeInfo)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -3120,7 +3228,7 @@ func file_mpi_v1_command_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_mpi_v1_command_proto_rawDesc), len(file_mpi_v1_command_proto_rawDesc)), NumEnums: 2, - NumMessages: 38, + NumMessages: 39, NumExtensions: 0, NumServices: 1, }, diff --git a/api/grpc/mpi/v1/command.pb.validate.go b/api/grpc/mpi/v1/command.pb.validate.go index 7a13f39da..34825aa11 100644 --- a/api/grpc/mpi/v1/command.pb.validate.go +++ b/api/grpc/mpi/v1/command.pb.validate.go @@ -4353,6 +4353,47 @@ func (m *InstanceRuntime) validate(all bool) error { } } + case *InstanceRuntime_NginxAppProtectRuntimeInfo: + if v == nil { + err := InstanceRuntimeValidationError{ + field: "Details", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetNginxAppProtectRuntimeInfo()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, InstanceRuntimeValidationError{ + field: "NginxAppProtectRuntimeInfo", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, InstanceRuntimeValidationError{ + field: "NginxAppProtectRuntimeInfo", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetNginxAppProtectRuntimeInfo()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return InstanceRuntimeValidationError{ + field: "NginxAppProtectRuntimeInfo", + reason: "embedded message failed validation", + cause: err, + } + } + } + default: _ = v // ensures v is used } @@ -4929,6 +4970,114 @@ var _ interface { ErrorName() string } = APIDetailsValidationError{} +// Validate checks the field values on NGINXAppProtectRuntimeInfo with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *NGINXAppProtectRuntimeInfo) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on NGINXAppProtectRuntimeInfo with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// NGINXAppProtectRuntimeInfoMultiError, or nil if none found. +func (m *NGINXAppProtectRuntimeInfo) ValidateAll() error { + return m.validate(true) +} + +func (m *NGINXAppProtectRuntimeInfo) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Release + + // no validation rules for AttackSignatureVersion + + // no validation rules for ThreatCampaignVersion + + if len(errors) > 0 { + return NGINXAppProtectRuntimeInfoMultiError(errors) + } + + return nil +} + +// NGINXAppProtectRuntimeInfoMultiError is an error wrapping multiple +// validation errors returned by NGINXAppProtectRuntimeInfo.ValidateAll() if +// the designated constraints aren't met. +type NGINXAppProtectRuntimeInfoMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m NGINXAppProtectRuntimeInfoMultiError) Error() string { + msgs := make([]string, 0, len(m)) + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m NGINXAppProtectRuntimeInfoMultiError) AllErrors() []error { return m } + +// NGINXAppProtectRuntimeInfoValidationError is the validation error returned +// by NGINXAppProtectRuntimeInfo.Validate if the designated constraints aren't met. +type NGINXAppProtectRuntimeInfoValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e NGINXAppProtectRuntimeInfoValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e NGINXAppProtectRuntimeInfoValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e NGINXAppProtectRuntimeInfoValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e NGINXAppProtectRuntimeInfoValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e NGINXAppProtectRuntimeInfoValidationError) ErrorName() string { + return "NGINXAppProtectRuntimeInfoValidationError" +} + +// Error satisfies the builtin error interface +func (e NGINXAppProtectRuntimeInfoValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sNGINXAppProtectRuntimeInfo.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = NGINXAppProtectRuntimeInfoValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = NGINXAppProtectRuntimeInfoValidationError{} + // Validate checks the field values on InstanceAction with the rules defined in // the proto definition for this message. If any rules are violated, the first // error encountered is returned, or nil if there are no violations. diff --git a/api/grpc/mpi/v1/command.proto b/api/grpc/mpi/v1/command.proto index e2229b753..9dd23ca8c 100644 --- a/api/grpc/mpi/v1/command.proto +++ b/api/grpc/mpi/v1/command.proto @@ -273,6 +273,8 @@ message InstanceMeta { INSTANCE_TYPE_NGINX_PLUS = 3; // NGINX Unit INSTANCE_TYPE_UNIT = 4; + // NGINX App Protect + INSTANCE_TYPE_NGINX_APP_PROTECT = 5; } // the types of instances possible InstanceType instance_type = 2; @@ -296,13 +298,15 @@ message InstanceRuntime { // the binary path location string binary_path = 2 [(buf.validate.field).string.prefix = "/"]; // the config path location - string config_path = 3 [(buf.validate.field).string.prefix = "/"]; + string config_path = 3 [(buf.validate.field).string.pattern = "^\\/.*|^$"]; // more detailed runtime objects oneof details { // NGINX runtime configuration settings like stub_status, usually read from the NGINX config or NGINX process NGINXRuntimeInfo nginx_runtime_info = 4; // NGINX Plus runtime configuration settings like api value, usually read from the NGINX config, NGINX process or NGINX Plus API NGINXPlusRuntimeInfo nginx_plus_runtime_info = 5; + // NGINX App Protect runtime information + NGINXAppProtectRuntimeInfo nginx_app_protect_runtime_info = 7; } // List of worker processes repeated InstanceChild instance_children = 6; @@ -350,6 +354,16 @@ message APIDetails { string listen = 2; } +// A set of runtime NGINX App Protect settings +message NGINXAppProtectRuntimeInfo { + // NGINX App Protect Release + string release = 1; + // Attack signature version + string attack_signature_version = 2; + // Threat campaign version + string threat_campaign_version = 3; +} + // A set of actions that can be performed on an instance message InstanceAction {} diff --git a/docs/proto/protos.md b/docs/proto/protos.md index 44e19670d..c612fbd85 100644 --- a/docs/proto/protos.md +++ b/docs/proto/protos.md @@ -65,6 +65,7 @@ - [InstanceRuntime](#mpi-v1-InstanceRuntime) - [ManagementPlaneRequest](#mpi-v1-ManagementPlaneRequest) - [MetricsServer](#mpi-v1-MetricsServer) + - [NGINXAppProtectRuntimeInfo](#mpi-v1-NGINXAppProtectRuntimeInfo) - [NGINXPlusAction](#mpi-v1-NGINXPlusAction) - [NGINXPlusRuntimeInfo](#mpi-v1-NGINXPlusRuntimeInfo) - [NGINXRuntimeInfo](#mpi-v1-NGINXRuntimeInfo) @@ -954,6 +955,7 @@ Meta-information relating to the reported instance | config_path | [string](#string) | | the config path location | | nginx_runtime_info | [NGINXRuntimeInfo](#mpi-v1-NGINXRuntimeInfo) | | NGINX runtime configuration settings like stub_status, usually read from the NGINX config or NGINX process | | nginx_plus_runtime_info | [NGINXPlusRuntimeInfo](#mpi-v1-NGINXPlusRuntimeInfo) | | NGINX Plus runtime configuration settings like api value, usually read from the NGINX config, NGINX process or NGINX Plus API | +| nginx_app_protect_runtime_info | [NGINXAppProtectRuntimeInfo](#mpi-v1-NGINXAppProtectRuntimeInfo) | | NGINX App Protect runtime information | | instance_children | [InstanceChild](#mpi-v1-InstanceChild) | repeated | List of worker processes | @@ -992,6 +994,23 @@ The metrics settings associated with origins (sources) of the metrics and destin + + +### NGINXAppProtectRuntimeInfo +A set of runtime NGINX App Protect settings + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| release | [string](#string) | | NGINX App Protect Release | +| attack_signature_version | [string](#string) | | Attack signature version | +| threat_campaign_version | [string](#string) | | Threat campaign version | + + + + + + ### NGINXPlusAction @@ -1209,6 +1228,7 @@ the types of instances possible | INSTANCE_TYPE_NGINX | 2 | NGINX | | INSTANCE_TYPE_NGINX_PLUS | 3 | NGINX Plus | | INSTANCE_TYPE_UNIT | 4 | NGINX Unit | +| INSTANCE_TYPE_NGINX_APP_PROTECT | 5 | NGINX App Protect | diff --git a/internal/watcher/health/health_watcher_service.go b/internal/watcher/health/health_watcher_service.go index c7b15c3f5..77ae72ea5 100644 --- a/internal/watcher/health/health_watcher_service.go +++ b/internal/watcher/health/health_watcher_service.go @@ -61,7 +61,8 @@ func (hw *HealthWatcherService) AddHealthWatcher(instances []*mpi.Instance) { hw.watchers[instance.GetInstanceMeta().GetInstanceId()] = watcher case mpi.InstanceMeta_INSTANCE_TYPE_AGENT: case mpi.InstanceMeta_INSTANCE_TYPE_UNSPECIFIED, - mpi.InstanceMeta_INSTANCE_TYPE_UNIT: + mpi.InstanceMeta_INSTANCE_TYPE_UNIT, + mpi.InstanceMeta_INSTANCE_TYPE_NGINX_APP_PROTECT: fallthrough default: slog.Warn("Health watcher not implemented", "instance_type", diff --git a/internal/watcher/instance/instance_watcher_service.go b/internal/watcher/instance/instance_watcher_service.go index 76e03d4dc..e163ee0c9 100644 --- a/internal/watcher/instance/instance_watcher_service.go +++ b/internal/watcher/instance/instance_watcher_service.go @@ -13,13 +13,15 @@ import ( "sync" "time" + "github.com/nginx/agent/v3/pkg/nginxprocess" + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/internal/watcher/process" + "github.com/nginx/agent/v3/internal/config" "github.com/nginx/agent/v3/internal/datasource/host/exec" "github.com/nginx/agent/v3/internal/logger" "github.com/nginx/agent/v3/internal/model" - "github.com/nginx/agent/v3/internal/watcher/process" - "github.com/nginx/agent/v3/pkg/nginxprocess" ) const defaultAgentPath = "/run/nginx-agent" @@ -40,16 +42,17 @@ type ( } InstanceWatcherService struct { - processOperator process.ProcessOperatorInterface - nginxConfigParser nginxConfigParser - executer exec.ExecInterface - agentConfig *config.Config - instanceCache map[string]*mpi.Instance - nginxConfigCache map[string]*model.NginxConfigContext - instancesChannel chan<- InstanceUpdatesMessage - nginxConfigContextChannel chan<- NginxConfigContextMessage - processParsers []processParser - cacheMutex sync.Mutex + processOperator process.ProcessOperatorInterface + nginxConfigParser nginxConfigParser + executer exec.ExecInterface + agentConfig *config.Config + instanceCache map[string]*mpi.Instance + nginxConfigCache map[string]*model.NginxConfigContext + instancesChannel chan<- InstanceUpdatesMessage + nginxConfigContextChannel chan<- NginxConfigContextMessage + nginxParser processParser + nginxAppProtectProcessParser processParser + cacheMutex sync.Mutex } InstanceUpdates struct { @@ -71,16 +74,15 @@ type ( func NewInstanceWatcherService(agentConfig *config.Config) *InstanceWatcherService { return &InstanceWatcherService{ - agentConfig: agentConfig, - processOperator: process.NewProcessOperator(), - processParsers: []processParser{ - NewNginxProcessParser(), - }, - nginxConfigParser: NewNginxConfigParser(agentConfig), - instanceCache: make(map[string]*mpi.Instance), - cacheMutex: sync.Mutex{}, - nginxConfigCache: make(map[string]*model.NginxConfigContext), - executer: &exec.Exec{}, + agentConfig: agentConfig, + processOperator: process.NewProcessOperator(), + nginxParser: NewNginxProcessParser(), + nginxAppProtectProcessParser: NewNginxAppProtectProcessParser(), + nginxConfigParser: NewNginxConfigParser(agentConfig), + instanceCache: make(map[string]*mpi.Instance), + cacheMutex: sync.Mutex{}, + nginxConfigCache: make(map[string]*model.NginxConfigContext), + executer: &exec.Exec{}, } } @@ -244,7 +246,7 @@ func (iw *InstanceWatcherService) instanceUpdates(ctx context.Context) ( ) { iw.cacheMutex.Lock() defer iw.cacheMutex.Unlock() - processes, err := iw.processOperator.Processes(ctx) + nginxProcesses, nginxAppProtectProcesses, err := iw.processOperator.Processes(ctx) if err != nil { return instanceUpdates, err } @@ -254,11 +256,14 @@ func (iw *InstanceWatcherService) instanceUpdates(ctx context.Context) ( agentInstance := iw.agentInstance(ctx) instancesFound[agentInstance.GetInstanceMeta().GetInstanceId()] = agentInstance - for _, parser := range iw.processParsers { - instances := parser.Parse(ctx, processes) - for _, instance := range instances { - instancesFound[instance.GetInstanceMeta().GetInstanceId()] = instance - } + nginxInstances := iw.nginxParser.Parse(ctx, nginxProcesses) + for _, instance := range nginxInstances { + instancesFound[instance.GetInstanceMeta().GetInstanceId()] = instance + } + + nginxAppProtectInstances := iw.nginxAppProtectProcessParser.Parse(ctx, nginxAppProtectProcesses) + for _, instance := range nginxAppProtectInstances { + instancesFound[instance.GetInstanceMeta().GetInstanceId()] = instance } newInstances, updatedInstances, deletedInstances := compareInstances(iw.instanceCache, instancesFound) diff --git a/internal/watcher/instance/instance_watcher_service_test.go b/internal/watcher/instance/instance_watcher_service_test.go index 470bb2151..6e869401f 100644 --- a/internal/watcher/instance/instance_watcher_service_test.go +++ b/internal/watcher/instance/instance_watcher_service_test.go @@ -28,7 +28,7 @@ func TestInstanceWatcherService_checkForUpdates(t *testing.T) { nginxConfigContext := testModel.GetConfigContext() fakeProcessWatcher := &processfakes.FakeProcessOperatorInterface{} - fakeProcessWatcher.ProcessesReturns(nil, nil) + fakeProcessWatcher.ProcessesReturns(nil, nil, nil) fakeProcessParser := &instancefakes.FakeProcessParser{} fakeProcessParser.ParseReturns(map[string]*mpi.Instance{ @@ -43,7 +43,8 @@ func TestInstanceWatcherService_checkForUpdates(t *testing.T) { instanceWatcherService := NewInstanceWatcherService(types.AgentConfig()) instanceWatcherService.processOperator = fakeProcessWatcher - instanceWatcherService.processParsers = []processParser{fakeProcessParser} + instanceWatcherService.nginxParser = fakeProcessParser + instanceWatcherService.nginxAppProtectProcessParser = fakeProcessParser instanceWatcherService.nginxConfigParser = fakeNginxConfigParser instanceWatcherService.instancesChannel = instanceUpdatesChannel instanceWatcherService.nginxConfigContextChannel = nginxConfigContextChannel @@ -131,7 +132,7 @@ func TestInstanceWatcherService_instanceUpdates(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { fakeProcessWatcher := &processfakes.FakeProcessOperatorInterface{} - fakeProcessWatcher.ProcessesReturns(nil, nil) + fakeProcessWatcher.ProcessesReturns(nil, nil, nil) fakeProcessParser := &instancefakes.FakeProcessParser{} fakeProcessParser.ParseReturns(test.parsedInstances) @@ -142,7 +143,8 @@ func TestInstanceWatcherService_instanceUpdates(t *testing.T) { instanceWatcherService := NewInstanceWatcherService(types.AgentConfig()) instanceWatcherService.processOperator = fakeProcessWatcher - instanceWatcherService.processParsers = []processParser{fakeProcessParser} + instanceWatcherService.nginxParser = fakeProcessParser + instanceWatcherService.nginxAppProtectProcessParser = fakeProcessParser instanceWatcherService.instanceCache = test.oldInstances instanceWatcherService.executer = fakeExec diff --git a/internal/watcher/instance/nginx_app_protect_process_parser.go b/internal/watcher/instance/nginx_app_protect_process_parser.go new file mode 100644 index 000000000..93001e86e --- /dev/null +++ b/internal/watcher/instance/nginx_app_protect_process_parser.go @@ -0,0 +1,144 @@ +// Copyright (c) F5, Inc. +// +// This source code is licensed under the Apache License, Version 2.0 license found in the +// LICENSE file in the root directory of this source tree. + +package instance + +import ( + "context" + "log/slog" + "os" + "strings" + + "github.com/nginx/agent/v3/pkg/nginxprocess" + + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/pkg/id" +) + +const ( + versionFilePath = "/opt/app_protect/VERSION" + releaseFilePath = "/opt/app_protect/RELEASE" + processName = "bd-socket-plugin" + attackSignatureVersionFilePath = "/opt/app_protect/var/update_files/signatures/version" + threatCampaignVersionFilePath = "/opt/app_protect/var/update_files/threat_campaigns/version" +) + +type ( + NginxAppProtectProcessParser struct { + versionFilePath string + releaseFilePath string + attackSignatureVersionFilePath string + threatCampaignVersionFilePath string + } +) + +var _ processParser = (*NginxAppProtectProcessParser)(nil) + +func NewNginxAppProtectProcessParser() *NginxAppProtectProcessParser { + return &NginxAppProtectProcessParser{ + versionFilePath: versionFilePath, + releaseFilePath: releaseFilePath, + attackSignatureVersionFilePath: attackSignatureVersionFilePath, + threatCampaignVersionFilePath: threatCampaignVersionFilePath, + } +} + +func (n NginxAppProtectProcessParser) Parse( + ctx context.Context, + processes []*nginxprocess.Process, +) map[string]*mpi.Instance { + instanceMap := make(map[string]*mpi.Instance) // key is instanceID + + for _, process := range processes { + if process.Name == processName { + instanceID := n.instanceID(process) + + binaryPath := process.Exe + if binaryPath == "" { + binaryPath = strings.Split(process.Cmd, " ")[0] + } + + instanceMap[instanceID] = &mpi.Instance{ + InstanceMeta: &mpi.InstanceMeta{ + InstanceId: instanceID, + InstanceType: mpi.InstanceMeta_INSTANCE_TYPE_NGINX_APP_PROTECT, + Version: n.instanceVersion(ctx), + }, + InstanceConfig: &mpi.InstanceConfig{}, + InstanceRuntime: &mpi.InstanceRuntime{ + ProcessId: process.PID, + BinaryPath: binaryPath, + ConfigPath: "", + Details: &mpi.InstanceRuntime_NginxAppProtectRuntimeInfo{ + NginxAppProtectRuntimeInfo: &mpi.NGINXAppProtectRuntimeInfo{ + Release: n.release(ctx), + AttackSignatureVersion: n.attackSignatureVersion(ctx), + ThreatCampaignVersion: n.threatCampaignVersion(ctx), + }, + }, + InstanceChildren: make([]*mpi.InstanceChild, 0), + }, + } + } + } + + return instanceMap +} + +func (n NginxAppProtectProcessParser) instanceID(process *nginxprocess.Process) string { + return id.Generate("%s", process.Exe) +} + +func (n NginxAppProtectProcessParser) instanceVersion(ctx context.Context) string { + version, err := os.ReadFile(n.versionFilePath) + if err != nil { + slog.WarnContext(ctx, "Unable to read NAP version file", "file_path", n.versionFilePath, "error", err) + return "" + } + + return strings.TrimSuffix(string(version), "\n") +} + +func (n NginxAppProtectProcessParser) release(ctx context.Context) string { + release, err := os.ReadFile(n.releaseFilePath) + if err != nil { + slog.WarnContext(ctx, "Unable to read NAP release file", "file_path", n.releaseFilePath, "error", err) + return "" + } + + return strings.TrimSuffix(string(release), "\n") +} + +func (n NginxAppProtectProcessParser) attackSignatureVersion(ctx context.Context) string { + attackSignatureVersion, err := os.ReadFile(n.attackSignatureVersionFilePath) + if err != nil { + slog.WarnContext( + ctx, + "Unable to read NAP attack signature version file", + "file_path", n.attackSignatureVersionFilePath, + "error", err, + ) + + return "" + } + + return string(attackSignatureVersion) +} + +func (n NginxAppProtectProcessParser) threatCampaignVersion(ctx context.Context) string { + threatCampaignVersion, err := os.ReadFile(n.threatCampaignVersionFilePath) + if err != nil { + slog.WarnContext( + ctx, + "Unable to read NAP threat campaign version file", + "file_path", n.threatCampaignVersionFilePath, + "error", err, + ) + + return "" + } + + return string(threatCampaignVersion) +} diff --git a/internal/watcher/instance/nginx_app_protect_process_parser_test.go b/internal/watcher/instance/nginx_app_protect_process_parser_test.go new file mode 100644 index 000000000..56ba2d1f0 --- /dev/null +++ b/internal/watcher/instance/nginx_app_protect_process_parser_test.go @@ -0,0 +1,116 @@ +// Copyright (c) F5, Inc. +// +// This source code is licensed under the Apache License, Version 2.0 license found in the +// LICENSE file in the root directory of this source tree. + +package instance + +import ( + "context" + "os" + "testing" + + "github.com/nginx/agent/v3/pkg/nginxprocess" + + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/test/helpers" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" +) + +func TestNginxAppProtectProcessParser_Parse(t *testing.T) { + ctx := context.Background() + + expectedInstance := &mpi.Instance{ + InstanceMeta: &mpi.InstanceMeta{ + InstanceId: "ca22d03b-06a4-3a2c-aa81-a6c4dd042ff4", + InstanceType: mpi.InstanceMeta_INSTANCE_TYPE_NGINX_APP_PROTECT, + Version: "5.144.0", + }, + InstanceConfig: &mpi.InstanceConfig{}, + InstanceRuntime: &mpi.InstanceRuntime{ + ProcessId: 1111, + BinaryPath: "/usr/share/ts/bin/bd-socket-plugin", + Details: &mpi.InstanceRuntime_NginxAppProtectRuntimeInfo{ + NginxAppProtectRuntimeInfo: &mpi.NGINXAppProtectRuntimeInfo{ + Release: "4.11.0", + AttackSignatureVersion: "2024.11.28", + ThreatCampaignVersion: "2024.12.02", + }, + }, + InstanceChildren: make([]*mpi.InstanceChild, 0), + }, + } + + processes := []*nginxprocess.Process{ + { + PID: 789, + PPID: 1234, + Name: "nginx", + Cmd: "nginx: worker process", + Exe: exePath, + }, + { + PID: 567, + PPID: 1234, + Name: "nginx", + Cmd: "nginx: worker process", + Exe: exePath, + }, + { + PID: 1234, + PPID: 1, + Name: "nginx", + Cmd: "nginx: master process /usr/local/opt/nginx/bin/nginx -g daemon off;", + Exe: exePath, + }, + { + PID: 1111, + PPID: 1, + Name: "bd-socket-plugin", + Cmd: "/usr/share/ts/bin/bd-socket-plugin tmm_count 4 no_static_config", + Exe: "/usr/share/ts/bin/bd-socket-plugin", + }, + } + + versionFile := helpers.CreateFileWithErrorCheck(t, os.TempDir(), "version") + defer helpers.RemoveFileWithErrorCheck(t, versionFile.Name()) + + _, err := versionFile.WriteString("5.144.0") + require.NoError(t, err) + + releaseFile := helpers.CreateFileWithErrorCheck(t, os.TempDir(), "release") + defer helpers.RemoveFileWithErrorCheck(t, releaseFile.Name()) + + _, err = releaseFile.WriteString("4.11.0") + require.NoError(t, err) + + attackSignatureVersionFile := helpers.CreateFileWithErrorCheck(t, os.TempDir(), "version") + defer helpers.RemoveFileWithErrorCheck(t, attackSignatureVersionFile.Name()) + + _, err = attackSignatureVersionFile.WriteString("2024.11.28") + require.NoError(t, err) + + threatCampaignVersionFile := helpers.CreateFileWithErrorCheck(t, os.TempDir(), "version") + defer helpers.RemoveFileWithErrorCheck(t, threatCampaignVersionFile.Name()) + + _, err = threatCampaignVersionFile.WriteString("2024.12.02") + require.NoError(t, err) + + nginxAppProtectProcessParser := NewNginxAppProtectProcessParser() + nginxAppProtectProcessParser.versionFilePath = versionFile.Name() + nginxAppProtectProcessParser.releaseFilePath = releaseFile.Name() + nginxAppProtectProcessParser.attackSignatureVersionFilePath = attackSignatureVersionFile.Name() + nginxAppProtectProcessParser.threatCampaignVersionFilePath = threatCampaignVersionFile.Name() + + instances := nginxAppProtectProcessParser.Parse(ctx, processes) + + assert.Len(t, instances, 1) + + assert.Truef( + t, + proto.Equal(instances["ca22d03b-06a4-3a2c-aa81-a6c4dd042ff4"], expectedInstance), + "expected %s, actual %s", expectedInstance, instances["ca22d03b-06a4-3a2c-aa81-a6c4dd042ff4"], + ) +} diff --git a/internal/watcher/process/process_operator.go b/internal/watcher/process/process_operator.go index 907a814e4..1ddffda1c 100644 --- a/internal/watcher/process/process_operator.go +++ b/internal/watcher/process/process_operator.go @@ -7,6 +7,9 @@ package process import ( "context" + "strings" + + "github.com/shirou/gopsutil/v4/process" "github.com/nginx/agent/v3/pkg/nginxprocess" ) @@ -18,21 +21,91 @@ type ( ProcessOperator struct{} ProcessOperatorInterface interface { - Processes(ctx context.Context) ([]*nginxprocess.Process, error) + Processes(ctx context.Context) ( + nginxProcesses []*nginxprocess.Process, + nginxAppProtectProcesses []*nginxprocess.Process, + err error, + ) Process(ctx context.Context, pid int32) (*nginxprocess.Process, error) } ) +func nginxFilter(ctx context.Context, p *process.Process) bool { + name, _ := p.NameWithContext(ctx) // slow: shells out to ps + if name != "nginx" { + return false + } + + cmdLine, _ := p.CmdlineWithContext(ctx) // slow: shells out to ps + // ignore nginx processes in the middle of an upgrade + if !strings.HasPrefix(cmdLine, "nginx:") || strings.Contains(cmdLine, "upgrade") { + return false + } + + return true +} + +func napFilter(ctx context.Context, p *process.Process) bool { + name, _ := p.NameWithContext(ctx) // slow: shells out to ps + return name == "bd-socket-plugin" +} + var _ ProcessOperatorInterface = (*ProcessOperator)(nil) func NewProcessOperator() *ProcessOperator { return &ProcessOperator{} } -func (pw *ProcessOperator) Processes(ctx context.Context) ([]*nginxprocess.Process, error) { - return nginxprocess.List(ctx) +func (pw *ProcessOperator) Processes(ctx context.Context) ( + nginxProcesses []*nginxprocess.Process, + nginxAppProtectProcesses []*nginxprocess.Process, + err error, +) { + processes, err := process.ProcessesWithContext(ctx) + if err != nil { + return nil, nil, err + } + + var filteredNginxProcesses []*process.Process + + for _, p := range processes { + if nginxFilter(ctx, p) { + filteredNginxProcesses = append(filteredNginxProcesses, p) + } else if napFilter(ctx, p) { + nginxAppProtectProcesses = append(nginxAppProtectProcesses, convertProcess(ctx, p)) + } + } + + nginxProcesses, err = nginxprocess.ListWithProcesses(ctx, filteredNginxProcesses) + if err != nil { + return nil, nil, err + } + + return nginxProcesses, nginxAppProtectProcesses, nil } func (pw *ProcessOperator) Process(ctx context.Context, pid int32) (*nginxprocess.Process, error) { - return nginxprocess.Find(ctx, pid, nginxprocess.WithStatus(true)) + proc, err := process.NewProcessWithContext(ctx, pid) + if err != nil { + return nil, err + } + + return convertProcess(ctx, proc), nil +} + +func convertProcess(ctx context.Context, proc *process.Process) *nginxprocess.Process { + ppid, _ := proc.PpidWithContext(ctx) + name, _ := proc.NameWithContext(ctx) + cmd, _ := proc.CmdlineWithContext(ctx) + exe, _ := proc.ExeWithContext(ctx) + status, _ := proc.StatusWithContext(ctx) + + return &nginxprocess.Process{ + PID: proc.Pid, + PPID: ppid, + Name: name, + Cmd: cmd, + Exe: exe, + Status: strings.Join(status, " "), + } } diff --git a/internal/watcher/process/processfakes/fake_process_operator_interface.go b/internal/watcher/process/processfakes/fake_process_operator_interface.go index 82fd7c96a..742c91e86 100644 --- a/internal/watcher/process/processfakes/fake_process_operator_interface.go +++ b/internal/watcher/process/processfakes/fake_process_operator_interface.go @@ -24,18 +24,20 @@ type FakeProcessOperatorInterface struct { result1 *nginxprocess.Process result2 error } - ProcessesStub func(context.Context) ([]*nginxprocess.Process, error) + ProcessesStub func(context.Context) ([]*nginxprocess.Process, []*nginxprocess.Process, error) processesMutex sync.RWMutex processesArgsForCall []struct { arg1 context.Context } processesReturns struct { result1 []*nginxprocess.Process - result2 error + result2 []*nginxprocess.Process + result3 error } processesReturnsOnCall map[int]struct { result1 []*nginxprocess.Process - result2 error + result2 []*nginxprocess.Process + result3 error } invocations map[string][][]interface{} invocationsMutex sync.RWMutex @@ -106,7 +108,7 @@ func (fake *FakeProcessOperatorInterface) ProcessReturnsOnCall(i int, result1 *n }{result1, result2} } -func (fake *FakeProcessOperatorInterface) Processes(arg1 context.Context) ([]*nginxprocess.Process, error) { +func (fake *FakeProcessOperatorInterface) Processes(arg1 context.Context) ([]*nginxprocess.Process, []*nginxprocess.Process, error) { fake.processesMutex.Lock() ret, specificReturn := fake.processesReturnsOnCall[len(fake.processesArgsForCall)] fake.processesArgsForCall = append(fake.processesArgsForCall, struct { @@ -120,9 +122,9 @@ func (fake *FakeProcessOperatorInterface) Processes(arg1 context.Context) ([]*ng return stub(arg1) } if specificReturn { - return ret.result1, ret.result2 + return ret.result1, ret.result2, ret.result3 } - return fakeReturns.result1, fakeReturns.result2 + return fakeReturns.result1, fakeReturns.result2, fakeReturns.result3 } func (fake *FakeProcessOperatorInterface) ProcessesCallCount() int { @@ -131,7 +133,7 @@ func (fake *FakeProcessOperatorInterface) ProcessesCallCount() int { return len(fake.processesArgsForCall) } -func (fake *FakeProcessOperatorInterface) ProcessesCalls(stub func(context.Context) ([]*nginxprocess.Process, error)) { +func (fake *FakeProcessOperatorInterface) ProcessesCalls(stub func(context.Context) ([]*nginxprocess.Process, []*nginxprocess.Process, error)) { fake.processesMutex.Lock() defer fake.processesMutex.Unlock() fake.ProcessesStub = stub @@ -144,30 +146,33 @@ func (fake *FakeProcessOperatorInterface) ProcessesArgsForCall(i int) context.Co return argsForCall.arg1 } -func (fake *FakeProcessOperatorInterface) ProcessesReturns(result1 []*nginxprocess.Process, result2 error) { +func (fake *FakeProcessOperatorInterface) ProcessesReturns(result1 []*nginxprocess.Process, result2 []*nginxprocess.Process, result3 error) { fake.processesMutex.Lock() defer fake.processesMutex.Unlock() fake.ProcessesStub = nil fake.processesReturns = struct { result1 []*nginxprocess.Process - result2 error - }{result1, result2} + result2 []*nginxprocess.Process + result3 error + }{result1, result2, result3} } -func (fake *FakeProcessOperatorInterface) ProcessesReturnsOnCall(i int, result1 []*nginxprocess.Process, result2 error) { +func (fake *FakeProcessOperatorInterface) ProcessesReturnsOnCall(i int, result1 []*nginxprocess.Process, result2 []*nginxprocess.Process, result3 error) { fake.processesMutex.Lock() defer fake.processesMutex.Unlock() fake.ProcessesStub = nil if fake.processesReturnsOnCall == nil { fake.processesReturnsOnCall = make(map[int]struct { result1 []*nginxprocess.Process - result2 error + result2 []*nginxprocess.Process + result3 error }) } fake.processesReturnsOnCall[i] = struct { result1 []*nginxprocess.Process - result2 error - }{result1, result2} + result2 []*nginxprocess.Process + result3 error + }{result1, result2, result3} } func (fake *FakeProcessOperatorInterface) Invocations() map[string][][]interface{} { diff --git a/pkg/nginxprocess/process.go b/pkg/nginxprocess/process.go index 53cca56fc..11173cd05 100644 --- a/pkg/nginxprocess/process.go +++ b/pkg/nginxprocess/process.go @@ -103,14 +103,26 @@ func convert(ctx context.Context, p *process.Process, o options) (*Process, erro // List returns a slice of all NGINX processes. Returns a zero-length slice if no NGINX processes are found. func List(ctx context.Context, opts ...Option) (ret []*Process, err error) { - o := options{} - for _, opt := range opts { - opt.apply(&o) - } processes, err := process.ProcessesWithContext(ctx) if err != nil { return nil, err } + + return ListWithProcesses(ctx, processes, opts...) +} + +// ListWithProcesses returns a slice of all NGINX processes. +// Returns a zero-length slice if no NGINX processes are found. +func ListWithProcesses( + ctx context.Context, + processes []*process.Process, + opts ...Option, +) (ret []*Process, err error) { + o := options{} + for _, opt := range opts { + opt.apply(&o) + } + for _, p := range processes { pr, cerr := convert(ctx, p, o) if IsNotNginxErr(cerr) { diff --git a/test/integration/grpc_management_plane_api_test.go b/test/integration/grpc_management_plane_api_test.go index bb12c8940..1d67a6292 100644 --- a/test/integration/grpc_management_plane_api_test.go +++ b/test/integration/grpc_management_plane_api_test.go @@ -599,6 +599,15 @@ func verifyConnection(t *testing.T, instancesLength int) string { assert.NotEmpty(t, instance.GetInstanceRuntime().GetBinaryPath()) assert.Equal(t, "/etc/nginx/nginx.conf", instance.GetInstanceRuntime().GetConfigPath()) + case mpi.InstanceMeta_INSTANCE_TYPE_NGINX_APP_PROTECT: + instanceMeta := instance.GetInstanceMeta() + assert.NotEmpty(t, instanceMeta.GetInstanceId()) + assert.NotEmpty(t, instanceMeta.GetVersion()) + + instanceRuntimeInfo := instance.GetInstanceRuntime().GetNginxAppProtectRuntimeInfo() + assert.NotEmpty(t, instanceRuntimeInfo.GetRelease()) + assert.NotEmpty(t, instanceRuntimeInfo.GetAttackSignatureVersion()) + assert.NotEmpty(t, instanceRuntimeInfo.GetThreatCampaignVersion()) case mpi.InstanceMeta_INSTANCE_TYPE_UNIT, mpi.InstanceMeta_INSTANCE_TYPE_UNSPECIFIED: fallthrough