diff --git a/api/grpc/mpi/v1/command.pb.go b/api/grpc/mpi/v1/command.pb.go index e390eb5ac..3b8d3acca 100644 --- a/api/grpc/mpi/v1/command.pb.go +++ b/api/grpc/mpi/v1/command.pb.go @@ -101,6 +101,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. @@ -111,13 +113,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, } ) @@ -1497,6 +1501,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"` @@ -1574,6 +1579,13 @@ func (x *InstanceRuntime) GetNginxPlusRuntimeInfo() *NGINXPlusRuntimeInfo { return nil } +func (x *InstanceRuntime) GetNginxAppProtectRuntimeInfo() *NGINXAppProtectRuntimeInfo { + if x, ok := x.GetDetails().(*InstanceRuntime_NginxAppProtectRuntimeInfo); ok { + return x.NginxAppProtectRuntimeInfo + } + return nil +} + func (x *InstanceRuntime) GetInstanceChildren() []*InstanceChild { if x != nil { return x.InstanceChildren @@ -1595,10 +1607,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 sizeCache protoimpl.SizeCache @@ -1820,6 +1839,71 @@ func (x *NGINXPlusRuntimeInfo) GetPlusApi() string { return "" } +// A set of runtime NGINX App Protect settings +type NGINXAppProtectRuntimeInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 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"` +} + +func (x *NGINXAppProtectRuntimeInfo) Reset() { + *x = NGINXAppProtectRuntimeInfo{} + mi := &file_mpi_v1_command_proto_msgTypes[26] + 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[26] + 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{26} +} + +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 @@ -1829,7 +1913,7 @@ type InstanceAction struct { func (x *InstanceAction) Reset() { *x = InstanceAction{} - mi := &file_mpi_v1_command_proto_msgTypes[26] + mi := &file_mpi_v1_command_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1841,7 +1925,7 @@ func (x *InstanceAction) String() string { func (*InstanceAction) ProtoMessage() {} func (x *InstanceAction) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[26] + mi := &file_mpi_v1_command_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1854,7 +1938,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{26} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{27} } // This contains a series of NGINX Agent configurations @@ -1879,7 +1963,7 @@ type AgentConfig struct { func (x *AgentConfig) Reset() { *x = AgentConfig{} - mi := &file_mpi_v1_command_proto_msgTypes[27] + mi := &file_mpi_v1_command_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1891,7 +1975,7 @@ func (x *AgentConfig) String() string { func (*AgentConfig) ProtoMessage() {} func (x *AgentConfig) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[27] + mi := &file_mpi_v1_command_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1904,7 +1988,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{27} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{28} } func (x *AgentConfig) GetCommand() *CommandServer { @@ -1958,7 +2042,7 @@ type CommandServer struct { func (x *CommandServer) Reset() { *x = CommandServer{} - mi := &file_mpi_v1_command_proto_msgTypes[28] + mi := &file_mpi_v1_command_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1970,7 +2054,7 @@ func (x *CommandServer) String() string { func (*CommandServer) ProtoMessage() {} func (x *CommandServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[28] + mi := &file_mpi_v1_command_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1983,7 +2067,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{28} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{29} } // The metrics settings associated with origins (sources) of the metrics and destinations (exporter) @@ -1995,7 +2079,7 @@ type MetricsServer struct { func (x *MetricsServer) Reset() { *x = MetricsServer{} - mi := &file_mpi_v1_command_proto_msgTypes[29] + mi := &file_mpi_v1_command_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2007,7 +2091,7 @@ func (x *MetricsServer) String() string { func (*MetricsServer) ProtoMessage() {} func (x *MetricsServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[29] + mi := &file_mpi_v1_command_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2020,7 +2104,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{29} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{30} } // The file settings associated with file server for configurations @@ -2032,7 +2116,7 @@ type FileServer struct { func (x *FileServer) Reset() { *x = FileServer{} - mi := &file_mpi_v1_command_proto_msgTypes[30] + mi := &file_mpi_v1_command_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2044,7 +2128,7 @@ func (x *FileServer) String() string { func (*FileServer) ProtoMessage() {} func (x *FileServer) ProtoReflect() protoreflect.Message { - mi := &file_mpi_v1_command_proto_msgTypes[30] + mi := &file_mpi_v1_command_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2057,7 +2141,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{30} + return file_mpi_v1_command_proto_rawDescGZIP(), []int{31} } var File_mpi_v1_command_proto protoreflect.FileDescriptor @@ -2242,7 +2326,7 @@ var file_mpi_v1_command_proto_rawDesc = []byte{ 0x63, 0x65, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 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, 0x63, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x22, 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, @@ -2252,7 +2336,7 @@ var file_mpi_v1_command_proto_rawDesc = []byte{ 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, 0x0a, 0x0c, 0x49, 0x6e, 0x73, + 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, 0x13, 0x49, 0x4e, 0x53, 0x54, @@ -2262,133 +2346,153 @@ var file_mpi_v1_command_proto_rawDesc = []byte{ 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, 0xa2, 0x02, 0x0a, 0x10, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x52, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x7a, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x59, 0xba, 0x48, - 0x56, 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x72, 0x69, - 0x12, 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, - 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x49, 0x20, 0x6f, 0x72, 0x20, 0x63, - 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x74, 0x68, 0x69, - 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, - 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 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, 0x9c, 0x03, 0x0a, 0x14, 0x4e, 0x47, 0x49, 0x4e, + 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, 0xe0, + 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, 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, - 0x12, 0x7a, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x59, 0xba, 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x72, 0x69, 0x12, 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x20, 0x55, 0x52, 0x49, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, - 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, - 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, 0x74, 0x0a, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x61, 0x70, 0x69, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x59, 0xba, 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x75, 0x72, 0x69, 0x12, 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, - 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, - 0x49, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x7c, 0x7c, - 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x07, 0x70, - 0x6c, 0x75, 0x73, 0x41, 0x70, 0x69, 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, - 0x0f, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 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, + 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, 0xa2, 0x02, 0x0a, 0x10, 0x4e, 0x47, 0x49, 0x4e, 0x58, 0x52, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x7a, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x59, 0xba, 0x48, 0x56, + 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x72, 0x69, 0x12, + 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, + 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x49, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 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, 0x9c, 0x03, 0x0a, 0x14, 0x4e, 0x47, 0x49, 0x4e, 0x58, + 0x50, 0x6c, 0x75, 0x73, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x7a, 0x0a, 0x0b, 0x73, 0x74, 0x75, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x59, 0xba, 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x72, 0x69, 0x12, 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, + 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, + 0x55, 0x52, 0x49, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 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, + 0x74, 0x0a, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x5f, 0x61, 0x70, 0x69, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x59, 0xba, 0x48, 0x56, 0xba, 0x01, 0x53, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x75, 0x72, 0x69, 0x12, 0x29, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, 0x73, + 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x49, + 0x20, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x7c, 0x7c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x07, 0x70, 0x6c, + 0x75, 0x73, 0x41, 0x70, 0x69, 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, 0x0f, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 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, - 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, + 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, 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, 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, + 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, 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, 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, + 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 ( @@ -2404,7 +2508,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, 31) +var file_mpi_v1_command_proto_msgTypes = make([]protoimpl.MessageInfo, 32) var file_mpi_v1_command_proto_goTypes = []any{ (InstanceHealth_InstanceHealthStatus)(0), // 0: mpi.v1.InstanceHealth.InstanceHealthStatus (InstanceMeta_InstanceType)(0), // 1: mpi.v1.InstanceMeta.InstanceType @@ -2434,67 +2538,69 @@ var file_mpi_v1_command_proto_goTypes = []any{ (*InstanceChild)(nil), // 25: mpi.v1.InstanceChild (*NGINXRuntimeInfo)(nil), // 26: mpi.v1.NGINXRuntimeInfo (*NGINXPlusRuntimeInfo)(nil), // 27: mpi.v1.NGINXPlusRuntimeInfo - (*InstanceAction)(nil), // 28: mpi.v1.InstanceAction - (*AgentConfig)(nil), // 29: mpi.v1.AgentConfig - (*CommandServer)(nil), // 30: mpi.v1.CommandServer - (*MetricsServer)(nil), // 31: mpi.v1.MetricsServer - (*FileServer)(nil), // 32: mpi.v1.FileServer - (*MessageMeta)(nil), // 33: mpi.v1.MessageMeta - (*CommandResponse)(nil), // 34: mpi.v1.CommandResponse - (*FileOverview)(nil), // 35: mpi.v1.FileOverview - (*structpb.Struct)(nil), // 36: google.protobuf.Struct + (*NGINXAppProtectRuntimeInfo)(nil), // 28: mpi.v1.NGINXAppProtectRuntimeInfo + (*InstanceAction)(nil), // 29: mpi.v1.InstanceAction + (*AgentConfig)(nil), // 30: mpi.v1.AgentConfig + (*CommandServer)(nil), // 31: mpi.v1.CommandServer + (*MetricsServer)(nil), // 32: mpi.v1.MetricsServer + (*FileServer)(nil), // 33: mpi.v1.FileServer + (*MessageMeta)(nil), // 34: mpi.v1.MessageMeta + (*CommandResponse)(nil), // 35: mpi.v1.CommandResponse + (*FileOverview)(nil), // 36: mpi.v1.FileOverview + (*structpb.Struct)(nil), // 37: google.protobuf.Struct } var file_mpi_v1_command_proto_depIdxs = []int32{ - 33, // 0: mpi.v1.CreateConnectionRequest.message_meta:type_name -> mpi.v1.MessageMeta + 34, // 0: mpi.v1.CreateConnectionRequest.message_meta:type_name -> mpi.v1.MessageMeta 3, // 1: mpi.v1.CreateConnectionRequest.resource:type_name -> mpi.v1.Resource 21, // 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 - 34, // 6: mpi.v1.CreateConnectionResponse.response:type_name -> mpi.v1.CommandResponse - 29, // 7: mpi.v1.CreateConnectionResponse.agent_config:type_name -> mpi.v1.AgentConfig - 33, // 8: mpi.v1.UpdateDataPlaneStatusRequest.message_meta:type_name -> mpi.v1.MessageMeta + 35, // 6: mpi.v1.CreateConnectionResponse.response:type_name -> mpi.v1.CommandResponse + 30, // 7: mpi.v1.CreateConnectionResponse.agent_config:type_name -> mpi.v1.AgentConfig + 34, // 8: mpi.v1.UpdateDataPlaneStatusRequest.message_meta:type_name -> mpi.v1.MessageMeta 3, // 9: mpi.v1.UpdateDataPlaneStatusRequest.resource:type_name -> mpi.v1.Resource 0, // 10: mpi.v1.InstanceHealth.instance_health_status:type_name -> mpi.v1.InstanceHealth.InstanceHealthStatus - 33, // 11: mpi.v1.UpdateDataPlaneHealthRequest.message_meta:type_name -> mpi.v1.MessageMeta + 34, // 11: mpi.v1.UpdateDataPlaneHealthRequest.message_meta:type_name -> mpi.v1.MessageMeta 10, // 12: mpi.v1.UpdateDataPlaneHealthRequest.instance_healths:type_name -> mpi.v1.InstanceHealth - 33, // 13: mpi.v1.DataPlaneResponse.message_meta:type_name -> mpi.v1.MessageMeta - 34, // 14: mpi.v1.DataPlaneResponse.command_response:type_name -> mpi.v1.CommandResponse - 33, // 15: mpi.v1.ManagementPlaneRequest.message_meta:type_name -> mpi.v1.MessageMeta + 34, // 13: mpi.v1.DataPlaneResponse.message_meta:type_name -> mpi.v1.MessageMeta + 35, // 14: mpi.v1.DataPlaneResponse.command_response:type_name -> mpi.v1.CommandResponse + 34, // 15: mpi.v1.ManagementPlaneRequest.message_meta:type_name -> mpi.v1.MessageMeta 15, // 16: mpi.v1.ManagementPlaneRequest.status_request:type_name -> mpi.v1.StatusRequest 16, // 17: mpi.v1.ManagementPlaneRequest.health_request:type_name -> mpi.v1.HealthRequest 17, // 18: mpi.v1.ManagementPlaneRequest.config_apply_request:type_name -> mpi.v1.ConfigApplyRequest 18, // 19: mpi.v1.ManagementPlaneRequest.config_upload_request:type_name -> mpi.v1.ConfigUploadRequest 19, // 20: mpi.v1.ManagementPlaneRequest.action_request:type_name -> mpi.v1.APIActionRequest 20, // 21: mpi.v1.ManagementPlaneRequest.command_status_request:type_name -> mpi.v1.CommandStatusRequest - 35, // 22: mpi.v1.ConfigApplyRequest.overview:type_name -> mpi.v1.FileOverview - 35, // 23: mpi.v1.ConfigUploadRequest.overview:type_name -> mpi.v1.FileOverview + 36, // 22: mpi.v1.ConfigApplyRequest.overview:type_name -> mpi.v1.FileOverview + 36, // 23: mpi.v1.ConfigUploadRequest.overview:type_name -> mpi.v1.FileOverview 22, // 24: mpi.v1.Instance.instance_meta:type_name -> mpi.v1.InstanceMeta 23, // 25: mpi.v1.Instance.instance_config:type_name -> mpi.v1.InstanceConfig 24, // 26: mpi.v1.Instance.instance_runtime:type_name -> mpi.v1.InstanceRuntime 1, // 27: mpi.v1.InstanceMeta.instance_type:type_name -> mpi.v1.InstanceMeta.InstanceType - 28, // 28: mpi.v1.InstanceConfig.actions:type_name -> mpi.v1.InstanceAction - 29, // 29: mpi.v1.InstanceConfig.agent_config:type_name -> mpi.v1.AgentConfig + 29, // 28: mpi.v1.InstanceConfig.actions:type_name -> mpi.v1.InstanceAction + 30, // 29: mpi.v1.InstanceConfig.agent_config:type_name -> mpi.v1.AgentConfig 26, // 30: mpi.v1.InstanceRuntime.nginx_runtime_info:type_name -> mpi.v1.NGINXRuntimeInfo 27, // 31: mpi.v1.InstanceRuntime.nginx_plus_runtime_info:type_name -> mpi.v1.NGINXPlusRuntimeInfo - 25, // 32: mpi.v1.InstanceRuntime.instance_children:type_name -> mpi.v1.InstanceChild - 30, // 33: mpi.v1.AgentConfig.command:type_name -> mpi.v1.CommandServer - 31, // 34: mpi.v1.AgentConfig.metrics:type_name -> mpi.v1.MetricsServer - 32, // 35: mpi.v1.AgentConfig.file:type_name -> mpi.v1.FileServer - 36, // 36: mpi.v1.AgentConfig.labels:type_name -> google.protobuf.Struct - 2, // 37: mpi.v1.CommandService.CreateConnection:input_type -> mpi.v1.CreateConnectionRequest - 8, // 38: mpi.v1.CommandService.UpdateDataPlaneStatus:input_type -> mpi.v1.UpdateDataPlaneStatusRequest - 11, // 39: mpi.v1.CommandService.UpdateDataPlaneHealth:input_type -> mpi.v1.UpdateDataPlaneHealthRequest - 13, // 40: mpi.v1.CommandService.Subscribe:input_type -> mpi.v1.DataPlaneResponse - 7, // 41: mpi.v1.CommandService.CreateConnection:output_type -> mpi.v1.CreateConnectionResponse - 9, // 42: mpi.v1.CommandService.UpdateDataPlaneStatus:output_type -> mpi.v1.UpdateDataPlaneStatusResponse - 12, // 43: mpi.v1.CommandService.UpdateDataPlaneHealth:output_type -> mpi.v1.UpdateDataPlaneHealthResponse - 14, // 44: mpi.v1.CommandService.Subscribe:output_type -> mpi.v1.ManagementPlaneRequest - 41, // [41:45] is the sub-list for method output_type - 37, // [37:41] is the sub-list for method input_type - 37, // [37:37] is the sub-list for extension type_name - 37, // [37:37] is the sub-list for extension extendee - 0, // [0:37] is the sub-list for field type_name + 28, // 32: mpi.v1.InstanceRuntime.nginx_app_protect_runtime_info:type_name -> mpi.v1.NGINXAppProtectRuntimeInfo + 25, // 33: mpi.v1.InstanceRuntime.instance_children:type_name -> mpi.v1.InstanceChild + 31, // 34: mpi.v1.AgentConfig.command:type_name -> mpi.v1.CommandServer + 32, // 35: mpi.v1.AgentConfig.metrics:type_name -> mpi.v1.MetricsServer + 33, // 36: mpi.v1.AgentConfig.file:type_name -> mpi.v1.FileServer + 37, // 37: mpi.v1.AgentConfig.labels:type_name -> google.protobuf.Struct + 2, // 38: mpi.v1.CommandService.CreateConnection:input_type -> mpi.v1.CreateConnectionRequest + 8, // 39: mpi.v1.CommandService.UpdateDataPlaneStatus:input_type -> mpi.v1.UpdateDataPlaneStatusRequest + 11, // 40: mpi.v1.CommandService.UpdateDataPlaneHealth:input_type -> mpi.v1.UpdateDataPlaneHealthRequest + 13, // 41: mpi.v1.CommandService.Subscribe:input_type -> mpi.v1.DataPlaneResponse + 7, // 42: mpi.v1.CommandService.CreateConnection:output_type -> mpi.v1.CreateConnectionResponse + 9, // 43: mpi.v1.CommandService.UpdateDataPlaneStatus:output_type -> mpi.v1.UpdateDataPlaneStatusResponse + 12, // 44: mpi.v1.CommandService.UpdateDataPlaneHealth:output_type -> mpi.v1.UpdateDataPlaneHealthResponse + 14, // 45: mpi.v1.CommandService.Subscribe:output_type -> mpi.v1.ManagementPlaneRequest + 42, // [42:46] is the sub-list for method output_type + 38, // [38:42] is the sub-list for method input_type + 38, // [38:38] is the sub-list for extension type_name + 38, // [38:38] is the sub-list for extension extendee + 0, // [0:38] is the sub-list for field type_name } func init() { file_mpi_v1_command_proto_init() } @@ -2522,6 +2628,7 @@ func file_mpi_v1_command_proto_init() { file_mpi_v1_command_proto_msgTypes[22].OneofWrappers = []any{ (*InstanceRuntime_NginxRuntimeInfo)(nil), (*InstanceRuntime_NginxPlusRuntimeInfo)(nil), + (*InstanceRuntime_NginxAppProtectRuntimeInfo)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -2529,7 +2636,7 @@ func file_mpi_v1_command_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_mpi_v1_command_proto_rawDesc, NumEnums: 2, - NumMessages: 31, + NumMessages: 32, 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 cc3233ba2..cc1610567 100644 --- a/api/grpc/mpi/v1/command.pb.validate.go +++ b/api/grpc/mpi/v1/command.pb.validate.go @@ -3385,6 +3385,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 } @@ -3777,6 +3818,114 @@ var _ interface { ErrorName() string } = NGINXPlusRuntimeInfoValidationError{} +// 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 { + var msgs []string + 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 f7879ea28..1d8dfc416 100644 --- a/api/grpc/mpi/v1/command.proto +++ b/api/grpc/mpi/v1/command.proto @@ -222,6 +222,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; @@ -252,6 +254,8 @@ message InstanceRuntime { 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; @@ -304,6 +308,16 @@ message NGINXPlusRuntimeInfo { }]; } +// 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 9e7a8afd6..401ae80f0 100644 --- a/docs/proto/protos.md +++ b/docs/proto/protos.md @@ -57,6 +57,7 @@ - [InstanceRuntime](#mpi-v1-InstanceRuntime) - [ManagementPlaneRequest](#mpi-v1-ManagementPlaneRequest) - [MetricsServer](#mpi-v1-MetricsServer) + - [NGINXAppProtectRuntimeInfo](#mpi-v1-NGINXAppProtectRuntimeInfo) - [NGINXPlusRuntimeInfo](#mpi-v1-NGINXPlusRuntimeInfo) - [NGINXRuntimeInfo](#mpi-v1-NGINXRuntimeInfo) - [ReleaseInfo](#mpi-v1-ReleaseInfo) @@ -813,6 +814,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 | @@ -851,6 +853,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 | + + + + + + ### NGINXPlusRuntimeInfo @@ -1017,6 +1036,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 011f18d6e..c39d031d2 100644 --- a/internal/watcher/health/health_watcher_service.go +++ b/internal/watcher/health/health_watcher_service.go @@ -59,7 +59,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 958ad9686..d402174d9 100644 --- a/internal/watcher/instance/instance_watcher_service.go +++ b/internal/watcher/instance/instance_watcher_service.go @@ -75,6 +75,7 @@ func NewInstanceWatcherService(agentConfig *config.Config) *InstanceWatcherServi processOperator: process.NewProcessOperator(), processParsers: []processParser{ NewNginxProcessParser(), + NewNginxAppProtectProcessParser(), }, nginxConfigParser: NewNginxConfigParser(agentConfig), instanceCache: make(map[string]*mpi.Instance), 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..c30fda213 --- /dev/null +++ b/internal/watcher/instance/nginx_app_protect_process_parser.go @@ -0,0 +1,135 @@ +// 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" + + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/internal/model" + "github.com/nginx/agent/v3/pkg/uuid" +) + +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 []*model.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) + + 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: process.Exe, + 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 *model.Process) string { + return uuid.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..28d5548e9 --- /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" + + mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1" + "github.com/nginx/agent/v3/internal/model" + "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", + ConfigPath: "", + 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 := []*model.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/test/integration/grpc_management_plane_api_test.go b/test/integration/grpc_management_plane_api_test.go index dd4a4b19b..c818602a3 100644 --- a/test/integration/grpc_management_plane_api_test.go +++ b/test/integration/grpc_management_plane_api_test.go @@ -583,6 +583,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