From 1a11bb67808fd0334652583ddc6e54045b2678e6 Mon Sep 17 00:00:00 2001 From: Torben Schmitz Date: Fri, 8 Aug 2025 03:14:07 -0700 Subject: [PATCH] Add a `DeleteFile` operation to the Fleetspeak FileStore and admin service, allowing for the removal of files previously stored via `StoreFile`. The changes include: - Implemented `DeleteFile` in all datastore implementations. - Implemented the `DeleteFile` RPC - Added a `deletefile` command to the Fleetspeak admin CLI. This provides feature parity with the existing `StoreFile` operation, enabling better management of files stored within Fleetspeak. PiperOrigin-RevId: 792550288 --- fleetspeak/src/server/admin/admin.go | 10 + fleetspeak/src/server/db/store.go | 4 + .../src/server/dbtesting/filestore_suite.go | 14 + fleetspeak/src/server/mysql/filestore.go | 7 + .../proto/fleetspeak_server/admin.pb.go | 529 ++++++++++-------- .../proto/fleetspeak_server/admin.proto | 8 + .../proto/fleetspeak_server/admin_grpc.pb.go | 40 ++ fleetspeak/src/server/spanner/filestore.go | 9 + fleetspeak/src/server/sqlite/filestore.go | 9 + fleetspeak/src/server/stats.go | 4 + 10 files changed, 403 insertions(+), 231 deletions(-) diff --git a/fleetspeak/src/server/admin/admin.go b/fleetspeak/src/server/admin/admin.go index 6df524ce..0a6544bb 100644 --- a/fleetspeak/src/server/admin/admin.go +++ b/fleetspeak/src/server/admin/admin.go @@ -296,6 +296,16 @@ func (s adminServer) StoreFile(ctx context.Context, req *spb.StoreFileRequest) ( return &fspb.EmptyMessage{}, nil } +func (s adminServer) DeleteFile(ctx context.Context, req *spb.DeleteFileRequest) (*fspb.EmptyMessage, error) { + if req.ServiceName == "" || req.FileName == "" { + return nil, errors.New("file must have service_name and file_name") + } + if err := s.store.DeleteFile(ctx, req.ServiceName, req.FileName); err != nil { + return nil, err + } + return &fspb.EmptyMessage{}, nil +} + func (s adminServer) KeepAlive(ctx context.Context, _ *fspb.EmptyMessage) (*fspb.EmptyMessage, error) { return &fspb.EmptyMessage{}, nil } diff --git a/fleetspeak/src/server/db/store.go b/fleetspeak/src/server/db/store.go index f06f97c0..04719c3f 100644 --- a/fleetspeak/src/server/db/store.go +++ b/fleetspeak/src/server/db/store.go @@ -373,6 +373,10 @@ type FileStore interface { // StoreFile stores data into the Filestore, organized by service and name. StoreFile(ctx context.Context, service, name string, data io.Reader) error + // DeleteFile deletes a file from the filestore. It is not an error if the + // file does not exist. + DeleteFile(ctx context.Context, service, name string) error + // StatFile returns the modification time of a file previously stored by // StoreFile. Returns ErrNotFound if not found. StatFile(ctx context.Context, servce, name string) (time.Time, error) diff --git a/fleetspeak/src/server/dbtesting/filestore_suite.go b/fleetspeak/src/server/dbtesting/filestore_suite.go index 75fd10c6..24820acb 100644 --- a/fleetspeak/src/server/dbtesting/filestore_suite.go +++ b/fleetspeak/src/server/dbtesting/filestore_suite.go @@ -53,6 +53,20 @@ func FileStoreTest(t *testing.T, fs db.Store) { if _, _, err := fs.ReadFile(ctx, "testService", "missingFile"); err == nil || !fs.IsNotFound(err) { t.Errorf("Wrong error for ReadFile(testService, missingFile), want IsNotFound(err)=true, got %v", err) } + + if err := fs.DeleteFile(ctx, "testService", "testFile"); err != nil { + t.Errorf("Error from DeleteFile(testService, testFile): %v", err) + } + if _, err := fs.StatFile(ctx, "testService", "testFile"); err == nil || !fs.IsNotFound(err) { + t.Errorf("Wrong error for StatFile(testService, testFile) after delete, want IsNotFound(err)=true, got %v", err) + } + // Deleting a non-existent file should not error. + if err := fs.DeleteFile(ctx, "testService", "testFile"); err != nil { + t.Errorf("Error from DeleteFile(testService, testFile) when file not present: %v", err) + } + if err := fs.DeleteFile(ctx, "testService", "missingFile"); err != nil { + t.Errorf("Error from DeleteFile(testService, missingFile): %v", err) + } } func fileStoreTestSuite(t *testing.T, env DbTestEnv) { diff --git a/fleetspeak/src/server/mysql/filestore.go b/fleetspeak/src/server/mysql/filestore.go index 9b0afa15..4b78bf6e 100644 --- a/fleetspeak/src/server/mysql/filestore.go +++ b/fleetspeak/src/server/mysql/filestore.go @@ -36,6 +36,13 @@ func (d *Datastore) StoreFile(ctx context.Context, service, name string, data io }) } +func (d *Datastore) DeleteFile(ctx context.Context, service, name string) error { + return d.runInTx(ctx, false, func(tx *sql.Tx) error { + _, err := tx.ExecContext(ctx, "DELETE FROM files WHERE service = ? AND name = ?", service, name) + return err + }) +} + func (d *Datastore) StatFile(ctx context.Context, service, name string) (time.Time, error) { var ts int64 diff --git a/fleetspeak/src/server/proto/fleetspeak_server/admin.pb.go b/fleetspeak/src/server/proto/fleetspeak_server/admin.pb.go index 62a05aa9..163b99b6 100644 --- a/fleetspeak/src/server/proto/fleetspeak_server/admin.pb.go +++ b/fleetspeak/src/server/proto/fleetspeak_server/admin.pb.go @@ -857,6 +857,59 @@ func (x *StoreFileRequest) GetData() []byte { return nil } +type DeleteFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + FileName string `protobuf:"bytes,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` +} + +func (x *DeleteFileRequest) Reset() { + *x = DeleteFileRequest{} + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteFileRequest) ProtoMessage() {} + +func (x *DeleteFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[16] + 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 DeleteFileRequest.ProtoReflect.Descriptor instead. +func (*DeleteFileRequest) Descriptor() ([]byte, []int) { + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{16} +} + +func (x *DeleteFileRequest) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *DeleteFileRequest) GetFileName() string { + if x != nil { + return x.FileName + } + return "" +} + type ListClientContactsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -867,7 +920,7 @@ type ListClientContactsRequest struct { func (x *ListClientContactsRequest) Reset() { *x = ListClientContactsRequest{} - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[16] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -879,7 +932,7 @@ func (x *ListClientContactsRequest) String() string { func (*ListClientContactsRequest) ProtoMessage() {} func (x *ListClientContactsRequest) ProtoReflect() protoreflect.Message { - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[16] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -892,7 +945,7 @@ func (x *ListClientContactsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListClientContactsRequest.ProtoReflect.Descriptor instead. func (*ListClientContactsRequest) Descriptor() ([]byte, []int) { - return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{16} + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{17} } func (x *ListClientContactsRequest) GetClientId() []byte { @@ -912,7 +965,7 @@ type ListClientContactsResponse struct { func (x *ListClientContactsResponse) Reset() { *x = ListClientContactsResponse{} - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[17] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -924,7 +977,7 @@ func (x *ListClientContactsResponse) String() string { func (*ListClientContactsResponse) ProtoMessage() {} func (x *ListClientContactsResponse) ProtoReflect() protoreflect.Message { - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[17] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -937,7 +990,7 @@ func (x *ListClientContactsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListClientContactsResponse.ProtoReflect.Descriptor instead. func (*ListClientContactsResponse) Descriptor() ([]byte, []int) { - return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{17} + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{18} } func (x *ListClientContactsResponse) GetContacts() []*ClientContact { @@ -957,7 +1010,7 @@ type StreamClientContactsRequest struct { func (x *StreamClientContactsRequest) Reset() { *x = StreamClientContactsRequest{} - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[18] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -969,7 +1022,7 @@ func (x *StreamClientContactsRequest) String() string { func (*StreamClientContactsRequest) ProtoMessage() {} func (x *StreamClientContactsRequest) ProtoReflect() protoreflect.Message { - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[18] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -982,7 +1035,7 @@ func (x *StreamClientContactsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StreamClientContactsRequest.ProtoReflect.Descriptor instead. func (*StreamClientContactsRequest) Descriptor() ([]byte, []int) { - return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{18} + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{19} } func (x *StreamClientContactsRequest) GetClientId() []byte { @@ -1002,7 +1055,7 @@ type StreamClientContactsResponse struct { func (x *StreamClientContactsResponse) Reset() { *x = StreamClientContactsResponse{} - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[19] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1014,7 +1067,7 @@ func (x *StreamClientContactsResponse) String() string { func (*StreamClientContactsResponse) ProtoMessage() {} func (x *StreamClientContactsResponse) ProtoReflect() protoreflect.Message { - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[19] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1027,7 +1080,7 @@ func (x *StreamClientContactsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StreamClientContactsResponse.ProtoReflect.Descriptor instead. func (*StreamClientContactsResponse) Descriptor() ([]byte, []int) { - return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{19} + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{20} } func (x *StreamClientContactsResponse) GetContact() *ClientContact { @@ -1050,7 +1103,7 @@ type ClientContact struct { func (x *ClientContact) Reset() { *x = ClientContact{} - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[20] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1062,7 +1115,7 @@ func (x *ClientContact) String() string { func (*ClientContact) ProtoMessage() {} func (x *ClientContact) ProtoReflect() protoreflect.Message { - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[20] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1075,7 +1128,7 @@ func (x *ClientContact) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientContact.ProtoReflect.Descriptor instead. func (*ClientContact) Descriptor() ([]byte, []int) { - return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{20} + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{21} } func (x *ClientContact) GetSentNonce() uint64 { @@ -1116,7 +1169,7 @@ type BlacklistClientRequest struct { func (x *BlacklistClientRequest) Reset() { *x = BlacklistClientRequest{} - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[21] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1128,7 +1181,7 @@ func (x *BlacklistClientRequest) String() string { func (*BlacklistClientRequest) ProtoMessage() {} func (x *BlacklistClientRequest) ProtoReflect() protoreflect.Message { - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[21] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1141,7 +1194,7 @@ func (x *BlacklistClientRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BlacklistClientRequest.ProtoReflect.Descriptor instead. func (*BlacklistClientRequest) Descriptor() ([]byte, []int) { - return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{21} + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{22} } func (x *BlacklistClientRequest) GetClientId() []byte { @@ -1163,7 +1216,7 @@ type FetchClientResourceUsageRecordsRequest struct { func (x *FetchClientResourceUsageRecordsRequest) Reset() { *x = FetchClientResourceUsageRecordsRequest{} - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[22] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1175,7 +1228,7 @@ func (x *FetchClientResourceUsageRecordsRequest) String() string { func (*FetchClientResourceUsageRecordsRequest) ProtoMessage() {} func (x *FetchClientResourceUsageRecordsRequest) ProtoReflect() protoreflect.Message { - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[22] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1188,7 +1241,7 @@ func (x *FetchClientResourceUsageRecordsRequest) ProtoReflect() protoreflect.Mes // Deprecated: Use FetchClientResourceUsageRecordsRequest.ProtoReflect.Descriptor instead. func (*FetchClientResourceUsageRecordsRequest) Descriptor() ([]byte, []int) { - return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{22} + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{23} } func (x *FetchClientResourceUsageRecordsRequest) GetClientId() []byte { @@ -1222,7 +1275,7 @@ type FetchClientResourceUsageRecordsResponse struct { func (x *FetchClientResourceUsageRecordsResponse) Reset() { *x = FetchClientResourceUsageRecordsResponse{} - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[23] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1234,7 +1287,7 @@ func (x *FetchClientResourceUsageRecordsResponse) String() string { func (*FetchClientResourceUsageRecordsResponse) ProtoMessage() {} func (x *FetchClientResourceUsageRecordsResponse) ProtoReflect() protoreflect.Message { - mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[23] + mi := &file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1247,7 +1300,7 @@ func (x *FetchClientResourceUsageRecordsResponse) ProtoReflect() protoreflect.Me // Deprecated: Use FetchClientResourceUsageRecordsResponse.ProtoReflect.Descriptor instead. func (*FetchClientResourceUsageRecordsResponse) Descriptor() ([]byte, []int) { - return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{23} + return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP(), []int{24} } func (x *FetchClientResourceUsageRecordsResponse) GetRecords() []*ClientResourceUsageRecord { @@ -1382,165 +1435,176 @@ var file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDesc = []b 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x22, 0x38, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x5a, 0x0a, - 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, - 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x22, 0x3a, 0x0a, 0x1b, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x5a, 0x0a, 0x1c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, - 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, - 0x74, 0x22, 0xba, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x06, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x6e, - 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x6e, - 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, - 0x69, 0x76, 0x65, 0x64, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x62, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x35, - 0x0a, 0x16, 0x42, 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xcb, 0x01, 0x0a, 0x26, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x43, 0x0a, - 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x3f, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x22, 0x71, 0x0a, 0x27, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, - 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x72, - 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x32, 0xb1, 0x0c, 0x0a, 0x05, 0x41, 0x64, 0x6d, 0x69, 0x6e, - 0x12, 0x58, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, - 0x61, 0x73, 0x74, 0x12, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x72, - 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, - 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x14, 0x4c, 0x69, - 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, - 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, - 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x66, 0x6c, + 0x61, 0x74, 0x61, 0x22, 0x53, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x38, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x49, 0x64, 0x22, 0x5a, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3c, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x22, 0x3a, + 0x0a, 0x1b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x5a, 0x0a, 0x1c, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, - 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x30, 0x01, 0x12, 0x73, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x12, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, - 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x74, + 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x06, 0x52, 0x09, 0x73, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x64, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, + 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x29, + 0x0a, 0x10, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x22, 0x35, 0x0a, 0x16, 0x42, 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x69, 0x73, 0x74, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xcb, 0x01, 0x0a, 0x26, 0x46, + 0x65, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x49, 0x64, 0x12, 0x43, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3f, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x71, 0x0a, 0x27, 0x46, 0x65, 0x74, 0x63, + 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, + 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x32, 0x81, 0x0d, 0x0a, 0x05, + 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x58, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, + 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, + 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, + 0x79, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x42, 0x72, 0x6f, + 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, + 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0b, 0x4c, 0x69, + 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x66, 0x6c, 0x65, 0x65, + 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x26, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0f, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x29, 0x2e, + 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, + 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x73, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x12, 0x2c, + 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x66, + 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, + 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, + 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, - 0x12, 0x2e, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x6d, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x2e, 0x66, 0x6c, 0x65, 0x65, - 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, - 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, - 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x13, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, - 0x61, 0x6b, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, - 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, - 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x12, - 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2d, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, + 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x6d, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, + 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x66, 0x6c, 0x65, + 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, + 0x65, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0d, 0x49, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x13, 0x2e, 0x66, 0x6c, 0x65, + 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, + 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x15, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, + 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, + 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0x00, 0x12, 0x73, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, + 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, + 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x30, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x7f, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x2e, 0x66, 0x6c, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x12, 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, + 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, + 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, + 0x69, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, + 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x4b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, + 0x76, 0x65, 0x12, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x66, + 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x42, 0x6c, 0x61, 0x63, + 0x6b, 0x6c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, - 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x09, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, - 0x23, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, - 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, - 0x12, 0x41, 0x0a, 0x09, 0x4b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x12, 0x18, 0x2e, - 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, - 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x42, 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x69, 0x73, 0x74, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, - 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x42, 0x6c, 0x61, 0x63, 0x6b, - 0x6c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x9a, 0x01, - 0x0a, 0x1f, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x73, 0x12, 0x39, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, + 0x42, 0x6c, 0x61, 0x63, 0x6b, 0x6c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, + 0x65, 0x61, 0x6b, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x00, 0x12, 0x9a, 0x01, 0x0a, 0x1f, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x39, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, + 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x3a, 0x2e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x66, - 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2f, 0x66, 0x6c, 0x65, 0x65, 0x74, - 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, - 0x6b, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x6f, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, + 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2f, + 0x66, 0x6c, 0x65, 0x65, 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x6c, 0x65, 0x65, + 0x74, 0x73, 0x70, 0x65, 0x61, 0x6b, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1555,7 +1619,7 @@ func file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescGZIP( return file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDescData } -var file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_goTypes = []any{ (*CreateBroadcastRequest)(nil), // 0: fleetspeak.server.CreateBroadcastRequest (*ListActiveBroadcastsRequest)(nil), // 1: fleetspeak.server.ListActiveBroadcastsRequest @@ -1573,71 +1637,74 @@ var file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_goTypes = []a (*GetPendingMessageCountResponse)(nil), // 13: fleetspeak.server.GetPendingMessageCountResponse (*GetMessageStatusResponse)(nil), // 14: fleetspeak.server.GetMessageStatusResponse (*StoreFileRequest)(nil), // 15: fleetspeak.server.StoreFileRequest - (*ListClientContactsRequest)(nil), // 16: fleetspeak.server.ListClientContactsRequest - (*ListClientContactsResponse)(nil), // 17: fleetspeak.server.ListClientContactsResponse - (*StreamClientContactsRequest)(nil), // 18: fleetspeak.server.StreamClientContactsRequest - (*StreamClientContactsResponse)(nil), // 19: fleetspeak.server.StreamClientContactsResponse - (*ClientContact)(nil), // 20: fleetspeak.server.ClientContact - (*BlacklistClientRequest)(nil), // 21: fleetspeak.server.BlacklistClientRequest - (*FetchClientResourceUsageRecordsRequest)(nil), // 22: fleetspeak.server.FetchClientResourceUsageRecordsRequest - (*FetchClientResourceUsageRecordsResponse)(nil), // 23: fleetspeak.server.FetchClientResourceUsageRecordsResponse - (*Broadcast)(nil), // 24: fleetspeak.server.Broadcast - (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp - (*fleetspeak.Label)(nil), // 26: fleetspeak.Label - (*fleetspeak.Message)(nil), // 27: fleetspeak.Message - (*fleetspeak.MessageResult)(nil), // 28: fleetspeak.MessageResult - (*ClientResourceUsageRecord)(nil), // 29: fleetspeak.server.ClientResourceUsageRecord - (*fleetspeak.EmptyMessage)(nil), // 30: fleetspeak.EmptyMessage + (*DeleteFileRequest)(nil), // 16: fleetspeak.server.DeleteFileRequest + (*ListClientContactsRequest)(nil), // 17: fleetspeak.server.ListClientContactsRequest + (*ListClientContactsResponse)(nil), // 18: fleetspeak.server.ListClientContactsResponse + (*StreamClientContactsRequest)(nil), // 19: fleetspeak.server.StreamClientContactsRequest + (*StreamClientContactsResponse)(nil), // 20: fleetspeak.server.StreamClientContactsResponse + (*ClientContact)(nil), // 21: fleetspeak.server.ClientContact + (*BlacklistClientRequest)(nil), // 22: fleetspeak.server.BlacklistClientRequest + (*FetchClientResourceUsageRecordsRequest)(nil), // 23: fleetspeak.server.FetchClientResourceUsageRecordsRequest + (*FetchClientResourceUsageRecordsResponse)(nil), // 24: fleetspeak.server.FetchClientResourceUsageRecordsResponse + (*Broadcast)(nil), // 25: fleetspeak.server.Broadcast + (*timestamppb.Timestamp)(nil), // 26: google.protobuf.Timestamp + (*fleetspeak.Label)(nil), // 27: fleetspeak.Label + (*fleetspeak.Message)(nil), // 28: fleetspeak.Message + (*fleetspeak.MessageResult)(nil), // 29: fleetspeak.MessageResult + (*ClientResourceUsageRecord)(nil), // 30: fleetspeak.server.ClientResourceUsageRecord + (*fleetspeak.EmptyMessage)(nil), // 31: fleetspeak.EmptyMessage } var file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_depIdxs = []int32{ - 24, // 0: fleetspeak.server.CreateBroadcastRequest.broadcast:type_name -> fleetspeak.server.Broadcast - 24, // 1: fleetspeak.server.ListActiveBroadcastsResponse.broadcasts:type_name -> fleetspeak.server.Broadcast + 25, // 0: fleetspeak.server.CreateBroadcastRequest.broadcast:type_name -> fleetspeak.server.Broadcast + 25, // 1: fleetspeak.server.ListActiveBroadcastsResponse.broadcasts:type_name -> fleetspeak.server.Broadcast 7, // 2: fleetspeak.server.ListClientsResponse.clients:type_name -> fleetspeak.server.Client - 25, // 3: fleetspeak.server.StreamClientIdsRequest.last_contact_after:type_name -> google.protobuf.Timestamp - 26, // 4: fleetspeak.server.Client.labels:type_name -> fleetspeak.Label - 25, // 5: fleetspeak.server.Client.last_contact_time:type_name -> google.protobuf.Timestamp - 25, // 6: fleetspeak.server.Client.last_clock:type_name -> google.protobuf.Timestamp - 27, // 7: fleetspeak.server.GetPendingMessagesResponse.messages:type_name -> fleetspeak.Message - 25, // 8: fleetspeak.server.GetMessageStatusResponse.creation_time:type_name -> google.protobuf.Timestamp - 28, // 9: fleetspeak.server.GetMessageStatusResponse.result:type_name -> fleetspeak.MessageResult - 20, // 10: fleetspeak.server.ListClientContactsResponse.contacts:type_name -> fleetspeak.server.ClientContact - 20, // 11: fleetspeak.server.StreamClientContactsResponse.contact:type_name -> fleetspeak.server.ClientContact - 25, // 12: fleetspeak.server.ClientContact.timestamp:type_name -> google.protobuf.Timestamp - 25, // 13: fleetspeak.server.FetchClientResourceUsageRecordsRequest.start_timestamp:type_name -> google.protobuf.Timestamp - 25, // 14: fleetspeak.server.FetchClientResourceUsageRecordsRequest.end_timestamp:type_name -> google.protobuf.Timestamp - 29, // 15: fleetspeak.server.FetchClientResourceUsageRecordsResponse.records:type_name -> fleetspeak.server.ClientResourceUsageRecord + 26, // 3: fleetspeak.server.StreamClientIdsRequest.last_contact_after:type_name -> google.protobuf.Timestamp + 27, // 4: fleetspeak.server.Client.labels:type_name -> fleetspeak.Label + 26, // 5: fleetspeak.server.Client.last_contact_time:type_name -> google.protobuf.Timestamp + 26, // 6: fleetspeak.server.Client.last_clock:type_name -> google.protobuf.Timestamp + 28, // 7: fleetspeak.server.GetPendingMessagesResponse.messages:type_name -> fleetspeak.Message + 26, // 8: fleetspeak.server.GetMessageStatusResponse.creation_time:type_name -> google.protobuf.Timestamp + 29, // 9: fleetspeak.server.GetMessageStatusResponse.result:type_name -> fleetspeak.MessageResult + 21, // 10: fleetspeak.server.ListClientContactsResponse.contacts:type_name -> fleetspeak.server.ClientContact + 21, // 11: fleetspeak.server.StreamClientContactsResponse.contact:type_name -> fleetspeak.server.ClientContact + 26, // 12: fleetspeak.server.ClientContact.timestamp:type_name -> google.protobuf.Timestamp + 26, // 13: fleetspeak.server.FetchClientResourceUsageRecordsRequest.start_timestamp:type_name -> google.protobuf.Timestamp + 26, // 14: fleetspeak.server.FetchClientResourceUsageRecordsRequest.end_timestamp:type_name -> google.protobuf.Timestamp + 30, // 15: fleetspeak.server.FetchClientResourceUsageRecordsResponse.records:type_name -> fleetspeak.server.ClientResourceUsageRecord 0, // 16: fleetspeak.server.Admin.CreateBroadcast:input_type -> fleetspeak.server.CreateBroadcastRequest 1, // 17: fleetspeak.server.Admin.ListActiveBroadcasts:input_type -> fleetspeak.server.ListActiveBroadcastsRequest 3, // 18: fleetspeak.server.Admin.ListClients:input_type -> fleetspeak.server.ListClientsRequest 5, // 19: fleetspeak.server.Admin.StreamClientIds:input_type -> fleetspeak.server.StreamClientIdsRequest - 16, // 20: fleetspeak.server.Admin.ListClientContacts:input_type -> fleetspeak.server.ListClientContactsRequest - 18, // 21: fleetspeak.server.Admin.StreamClientContacts:input_type -> fleetspeak.server.StreamClientContactsRequest + 17, // 20: fleetspeak.server.Admin.ListClientContacts:input_type -> fleetspeak.server.ListClientContactsRequest + 19, // 21: fleetspeak.server.Admin.StreamClientContacts:input_type -> fleetspeak.server.StreamClientContactsRequest 8, // 22: fleetspeak.server.Admin.GetMessageStatus:input_type -> fleetspeak.server.GetMessageStatusRequest - 27, // 23: fleetspeak.server.Admin.InsertMessage:input_type -> fleetspeak.Message + 28, // 23: fleetspeak.server.Admin.InsertMessage:input_type -> fleetspeak.Message 9, // 24: fleetspeak.server.Admin.DeletePendingMessages:input_type -> fleetspeak.server.DeletePendingMessagesRequest 10, // 25: fleetspeak.server.Admin.GetPendingMessages:input_type -> fleetspeak.server.GetPendingMessagesRequest 12, // 26: fleetspeak.server.Admin.GetPendingMessageCount:input_type -> fleetspeak.server.GetPendingMessageCountRequest 15, // 27: fleetspeak.server.Admin.StoreFile:input_type -> fleetspeak.server.StoreFileRequest - 30, // 28: fleetspeak.server.Admin.KeepAlive:input_type -> fleetspeak.EmptyMessage - 21, // 29: fleetspeak.server.Admin.BlacklistClient:input_type -> fleetspeak.server.BlacklistClientRequest - 22, // 30: fleetspeak.server.Admin.FetchClientResourceUsageRecords:input_type -> fleetspeak.server.FetchClientResourceUsageRecordsRequest - 30, // 31: fleetspeak.server.Admin.CreateBroadcast:output_type -> fleetspeak.EmptyMessage - 2, // 32: fleetspeak.server.Admin.ListActiveBroadcasts:output_type -> fleetspeak.server.ListActiveBroadcastsResponse - 4, // 33: fleetspeak.server.Admin.ListClients:output_type -> fleetspeak.server.ListClientsResponse - 6, // 34: fleetspeak.server.Admin.StreamClientIds:output_type -> fleetspeak.server.StreamClientIdsResponse - 17, // 35: fleetspeak.server.Admin.ListClientContacts:output_type -> fleetspeak.server.ListClientContactsResponse - 19, // 36: fleetspeak.server.Admin.StreamClientContacts:output_type -> fleetspeak.server.StreamClientContactsResponse - 14, // 37: fleetspeak.server.Admin.GetMessageStatus:output_type -> fleetspeak.server.GetMessageStatusResponse - 30, // 38: fleetspeak.server.Admin.InsertMessage:output_type -> fleetspeak.EmptyMessage - 30, // 39: fleetspeak.server.Admin.DeletePendingMessages:output_type -> fleetspeak.EmptyMessage - 11, // 40: fleetspeak.server.Admin.GetPendingMessages:output_type -> fleetspeak.server.GetPendingMessagesResponse - 13, // 41: fleetspeak.server.Admin.GetPendingMessageCount:output_type -> fleetspeak.server.GetPendingMessageCountResponse - 30, // 42: fleetspeak.server.Admin.StoreFile:output_type -> fleetspeak.EmptyMessage - 30, // 43: fleetspeak.server.Admin.KeepAlive:output_type -> fleetspeak.EmptyMessage - 30, // 44: fleetspeak.server.Admin.BlacklistClient:output_type -> fleetspeak.EmptyMessage - 23, // 45: fleetspeak.server.Admin.FetchClientResourceUsageRecords:output_type -> fleetspeak.server.FetchClientResourceUsageRecordsResponse - 31, // [31:46] is the sub-list for method output_type - 16, // [16:31] is the sub-list for method input_type + 16, // 28: fleetspeak.server.Admin.DeleteFile:input_type -> fleetspeak.server.DeleteFileRequest + 31, // 29: fleetspeak.server.Admin.KeepAlive:input_type -> fleetspeak.EmptyMessage + 22, // 30: fleetspeak.server.Admin.BlacklistClient:input_type -> fleetspeak.server.BlacklistClientRequest + 23, // 31: fleetspeak.server.Admin.FetchClientResourceUsageRecords:input_type -> fleetspeak.server.FetchClientResourceUsageRecordsRequest + 31, // 32: fleetspeak.server.Admin.CreateBroadcast:output_type -> fleetspeak.EmptyMessage + 2, // 33: fleetspeak.server.Admin.ListActiveBroadcasts:output_type -> fleetspeak.server.ListActiveBroadcastsResponse + 4, // 34: fleetspeak.server.Admin.ListClients:output_type -> fleetspeak.server.ListClientsResponse + 6, // 35: fleetspeak.server.Admin.StreamClientIds:output_type -> fleetspeak.server.StreamClientIdsResponse + 18, // 36: fleetspeak.server.Admin.ListClientContacts:output_type -> fleetspeak.server.ListClientContactsResponse + 20, // 37: fleetspeak.server.Admin.StreamClientContacts:output_type -> fleetspeak.server.StreamClientContactsResponse + 14, // 38: fleetspeak.server.Admin.GetMessageStatus:output_type -> fleetspeak.server.GetMessageStatusResponse + 31, // 39: fleetspeak.server.Admin.InsertMessage:output_type -> fleetspeak.EmptyMessage + 31, // 40: fleetspeak.server.Admin.DeletePendingMessages:output_type -> fleetspeak.EmptyMessage + 11, // 41: fleetspeak.server.Admin.GetPendingMessages:output_type -> fleetspeak.server.GetPendingMessagesResponse + 13, // 42: fleetspeak.server.Admin.GetPendingMessageCount:output_type -> fleetspeak.server.GetPendingMessageCountResponse + 31, // 43: fleetspeak.server.Admin.StoreFile:output_type -> fleetspeak.EmptyMessage + 31, // 44: fleetspeak.server.Admin.DeleteFile:output_type -> fleetspeak.EmptyMessage + 31, // 45: fleetspeak.server.Admin.KeepAlive:output_type -> fleetspeak.EmptyMessage + 31, // 46: fleetspeak.server.Admin.BlacklistClient:output_type -> fleetspeak.EmptyMessage + 24, // 47: fleetspeak.server.Admin.FetchClientResourceUsageRecords:output_type -> fleetspeak.server.FetchClientResourceUsageRecordsResponse + 32, // [32:48] is the sub-list for method output_type + 16, // [16:32] is the sub-list for method input_type 16, // [16:16] is the sub-list for extension type_name 16, // [16:16] is the sub-list for extension extendee 0, // [0:16] is the sub-list for field type_name @@ -1656,7 +1723,7 @@ func file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_fleetspeak_src_server_proto_fleetspeak_server_admin_proto_rawDesc, NumEnums: 0, - NumMessages: 24, + NumMessages: 25, NumExtensions: 0, NumServices: 1, }, diff --git a/fleetspeak/src/server/proto/fleetspeak_server/admin.proto b/fleetspeak/src/server/proto/fleetspeak_server/admin.proto index 2a8cbdbe..85cd76e1 100644 --- a/fleetspeak/src/server/proto/fleetspeak_server/admin.proto +++ b/fleetspeak/src/server/proto/fleetspeak_server/admin.proto @@ -92,6 +92,11 @@ message StoreFileRequest { bytes data = 3; } +message DeleteFileRequest { + string service_name = 1; + string file_name = 2; +} + message ListClientContactsRequest { bytes client_id = 1; } @@ -179,6 +184,9 @@ service Admin { // StoreFile inserts a file into the Fleetspeak system. rpc StoreFile(StoreFileRequest) returns (fleetspeak.EmptyMessage) {} + // DeleteFile deletes a file from the Fleetspeak system. + rpc DeleteFile(DeleteFileRequest) returns (fleetspeak.EmptyMessage) {} + // KeepAlive does as little as possible. rpc KeepAlive(fleetspeak.EmptyMessage) returns (fleetspeak.EmptyMessage) {} diff --git a/fleetspeak/src/server/proto/fleetspeak_server/admin_grpc.pb.go b/fleetspeak/src/server/proto/fleetspeak_server/admin_grpc.pb.go index e7cd9073..4353d0be 100644 --- a/fleetspeak/src/server/proto/fleetspeak_server/admin_grpc.pb.go +++ b/fleetspeak/src/server/proto/fleetspeak_server/admin_grpc.pb.go @@ -32,6 +32,7 @@ const ( Admin_GetPendingMessages_FullMethodName = "/fleetspeak.server.Admin/GetPendingMessages" Admin_GetPendingMessageCount_FullMethodName = "/fleetspeak.server.Admin/GetPendingMessageCount" Admin_StoreFile_FullMethodName = "/fleetspeak.server.Admin/StoreFile" + Admin_DeleteFile_FullMethodName = "/fleetspeak.server.Admin/DeleteFile" Admin_KeepAlive_FullMethodName = "/fleetspeak.server.Admin/KeepAlive" Admin_BlacklistClient_FullMethodName = "/fleetspeak.server.Admin/BlacklistClient" Admin_FetchClientResourceUsageRecords_FullMethodName = "/fleetspeak.server.Admin/FetchClientResourceUsageRecords" @@ -69,6 +70,8 @@ type AdminClient interface { GetPendingMessageCount(ctx context.Context, in *GetPendingMessageCountRequest, opts ...grpc.CallOption) (*GetPendingMessageCountResponse, error) // StoreFile inserts a file into the Fleetspeak system. StoreFile(ctx context.Context, in *StoreFileRequest, opts ...grpc.CallOption) (*fleetspeak.EmptyMessage, error) + // DeleteFile deletes a file from the Fleetspeak system. + DeleteFile(ctx context.Context, in *DeleteFileRequest, opts ...grpc.CallOption) (*fleetspeak.EmptyMessage, error) // KeepAlive does as little as possible. KeepAlive(ctx context.Context, in *fleetspeak.EmptyMessage, opts ...grpc.CallOption) (*fleetspeak.EmptyMessage, error) // BlacklistClient marks a client_id as invalid, forcing all Fleetspeak @@ -225,6 +228,16 @@ func (c *adminClient) StoreFile(ctx context.Context, in *StoreFileRequest, opts return out, nil } +func (c *adminClient) DeleteFile(ctx context.Context, in *DeleteFileRequest, opts ...grpc.CallOption) (*fleetspeak.EmptyMessage, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(fleetspeak.EmptyMessage) + err := c.cc.Invoke(ctx, Admin_DeleteFile_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *adminClient) KeepAlive(ctx context.Context, in *fleetspeak.EmptyMessage, opts ...grpc.CallOption) (*fleetspeak.EmptyMessage, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(fleetspeak.EmptyMessage) @@ -287,6 +300,8 @@ type AdminServer interface { GetPendingMessageCount(context.Context, *GetPendingMessageCountRequest) (*GetPendingMessageCountResponse, error) // StoreFile inserts a file into the Fleetspeak system. StoreFile(context.Context, *StoreFileRequest) (*fleetspeak.EmptyMessage, error) + // DeleteFile deletes a file from the Fleetspeak system. + DeleteFile(context.Context, *DeleteFileRequest) (*fleetspeak.EmptyMessage, error) // KeepAlive does as little as possible. KeepAlive(context.Context, *fleetspeak.EmptyMessage) (*fleetspeak.EmptyMessage, error) // BlacklistClient marks a client_id as invalid, forcing all Fleetspeak @@ -341,6 +356,9 @@ func (UnimplementedAdminServer) GetPendingMessageCount(context.Context, *GetPend func (UnimplementedAdminServer) StoreFile(context.Context, *StoreFileRequest) (*fleetspeak.EmptyMessage, error) { return nil, status.Errorf(codes.Unimplemented, "method StoreFile not implemented") } +func (UnimplementedAdminServer) DeleteFile(context.Context, *DeleteFileRequest) (*fleetspeak.EmptyMessage, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteFile not implemented") +} func (UnimplementedAdminServer) KeepAlive(context.Context, *fleetspeak.EmptyMessage) (*fleetspeak.EmptyMessage, error) { return nil, status.Errorf(codes.Unimplemented, "method KeepAlive not implemented") } @@ -573,6 +591,24 @@ func _Admin_StoreFile_Handler(srv interface{}, ctx context.Context, dec func(int return interceptor(ctx, in, info, handler) } +func _Admin_DeleteFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).DeleteFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Admin_DeleteFile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).DeleteFile(ctx, req.(*DeleteFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Admin_KeepAlive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(fleetspeak.EmptyMessage) if err := dec(in); err != nil { @@ -674,6 +710,10 @@ var Admin_ServiceDesc = grpc.ServiceDesc{ MethodName: "StoreFile", Handler: _Admin_StoreFile_Handler, }, + { + MethodName: "DeleteFile", + Handler: _Admin_DeleteFile_Handler, + }, { MethodName: "KeepAlive", Handler: _Admin_KeepAlive_Handler, diff --git a/fleetspeak/src/server/spanner/filestore.go b/fleetspeak/src/server/spanner/filestore.go index 22e4c0e9..e9d7cdd9 100644 --- a/fleetspeak/src/server/spanner/filestore.go +++ b/fleetspeak/src/server/spanner/filestore.go @@ -45,6 +45,15 @@ func (d *Datastore) tryStoreFile(txn *spanner.ReadWriteTransaction, service, nam return err } +// DeleteFile implements db.FileStore. +func (d *Datastore) DeleteFile(ctx context.Context, service, name string) error { + _, err := d.dbClient.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error { + m := spanner.Delete(d.files, spanner.Key{service, name}) + return txn.BufferWrite([]*spanner.Mutation{m}) + }) + return err +} + // StatFile implements db.FileStore. func (d *Datastore) StatFile(ctx context.Context, service, name string) (time.Time, error) { txn := d.dbClient.Single() diff --git a/fleetspeak/src/server/sqlite/filestore.go b/fleetspeak/src/server/sqlite/filestore.go index f416e7d5..72c095ec 100644 --- a/fleetspeak/src/server/sqlite/filestore.go +++ b/fleetspeak/src/server/sqlite/filestore.go @@ -38,6 +38,15 @@ func (d *Datastore) StoreFile(ctx context.Context, service, name string, data io }) } +func (d *Datastore) DeleteFile(ctx context.Context, service, name string) error { + d.l.Lock() + defer d.l.Unlock() + return d.runInTx(func(tx *sql.Tx) error { + _, err := tx.ExecContext(ctx, "DELETE FROM files WHERE service = ? AND name = ?", service, name) + return err + }) +} + func (d *Datastore) StatFile(ctx context.Context, service, name string) (time.Time, error) { d.l.Lock() defer d.l.Unlock() diff --git a/fleetspeak/src/server/stats.go b/fleetspeak/src/server/stats.go index 6d342a22..eaa0a6b2 100644 --- a/fleetspeak/src/server/stats.go +++ b/fleetspeak/src/server/stats.go @@ -282,6 +282,10 @@ func (d MonitoredDatastore) StoreFile(ctx context.Context, service, name string, return d.D.StoreFile(ctx, service, name, data) } +func (d MonitoredDatastore) DeleteFile(ctx context.Context, service, name string) error { + return d.D.DeleteFile(ctx, service, name) +} + func (d MonitoredDatastore) StatFile(ctx context.Context, service, name string) (time.Time, error) { return d.D.StatFile(ctx, service, name) }