1
0
mirror of https://github.com/amir20/dozzle.git synced 2025-12-21 21:33:18 +01:00

feat: enables container filter to be configured at multiple places

This commit is contained in:
Amir Raminfar
2024-12-13 11:59:39 -08:00
parent a62cef7e25
commit 74b5adad00
20 changed files with 468 additions and 350 deletions

View File

@@ -303,8 +303,16 @@ func (c *Client) FindContainer(ctx context.Context, containerID string) (docker.
}, nil }, nil
} }
func (c *Client) ListContainers(ctx context.Context) ([]docker.Container, error) { func (c *Client) ListContainers(ctx context.Context, filter docker.ContainerFilter) ([]docker.Container, error) {
response, err := c.client.ListContainers(ctx, &pb.ListContainersRequest{}) in := &pb.ListContainersRequest{}
if filter != nil {
for k, v := range filter {
in.Filter[k] = &pb.RepeatedString{Values: v}
}
}
response, err := c.client.ListContainers(ctx, in)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.35.1
// protoc v5.28.3 // protoc v5.29.1
// source: rpc.proto // source: rpc.proto
package pb package pb
@@ -25,6 +25,8 @@ type ListContainersRequest struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Filter map[string]*RepeatedString `protobuf:"bytes,1,rep,name=filter,proto3" json:"filter,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
} }
func (x *ListContainersRequest) Reset() { func (x *ListContainersRequest) Reset() {
@@ -57,6 +59,58 @@ func (*ListContainersRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{0} return file_rpc_proto_rawDescGZIP(), []int{0}
} }
func (x *ListContainersRequest) GetFilter() map[string]*RepeatedString {
if x != nil {
return x.Filter
}
return nil
}
type RepeatedString struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Values []string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
}
func (x *RepeatedString) Reset() {
*x = RepeatedString{}
mi := &file_rpc_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RepeatedString) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RepeatedString) ProtoMessage() {}
func (x *RepeatedString) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[1]
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 RepeatedString.ProtoReflect.Descriptor instead.
func (*RepeatedString) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{1}
}
func (x *RepeatedString) GetValues() []string {
if x != nil {
return x.Values
}
return nil
}
type ListContainersResponse struct { type ListContainersResponse struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@@ -67,7 +121,7 @@ type ListContainersResponse struct {
func (x *ListContainersResponse) Reset() { func (x *ListContainersResponse) Reset() {
*x = ListContainersResponse{} *x = ListContainersResponse{}
mi := &file_rpc_proto_msgTypes[1] mi := &file_rpc_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -79,7 +133,7 @@ func (x *ListContainersResponse) String() string {
func (*ListContainersResponse) ProtoMessage() {} func (*ListContainersResponse) ProtoMessage() {}
func (x *ListContainersResponse) ProtoReflect() protoreflect.Message { func (x *ListContainersResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[1] mi := &file_rpc_proto_msgTypes[2]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -92,7 +146,7 @@ func (x *ListContainersResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListContainersResponse.ProtoReflect.Descriptor instead. // Deprecated: Use ListContainersResponse.ProtoReflect.Descriptor instead.
func (*ListContainersResponse) Descriptor() ([]byte, []int) { func (*ListContainersResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{1} return file_rpc_proto_rawDescGZIP(), []int{2}
} }
func (x *ListContainersResponse) GetContainers() []*Container { func (x *ListContainersResponse) GetContainers() []*Container {
@@ -112,7 +166,7 @@ type FindContainerRequest struct {
func (x *FindContainerRequest) Reset() { func (x *FindContainerRequest) Reset() {
*x = FindContainerRequest{} *x = FindContainerRequest{}
mi := &file_rpc_proto_msgTypes[2] mi := &file_rpc_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -124,7 +178,7 @@ func (x *FindContainerRequest) String() string {
func (*FindContainerRequest) ProtoMessage() {} func (*FindContainerRequest) ProtoMessage() {}
func (x *FindContainerRequest) ProtoReflect() protoreflect.Message { func (x *FindContainerRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[2] mi := &file_rpc_proto_msgTypes[3]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -137,7 +191,7 @@ func (x *FindContainerRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use FindContainerRequest.ProtoReflect.Descriptor instead. // Deprecated: Use FindContainerRequest.ProtoReflect.Descriptor instead.
func (*FindContainerRequest) Descriptor() ([]byte, []int) { func (*FindContainerRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{2} return file_rpc_proto_rawDescGZIP(), []int{3}
} }
func (x *FindContainerRequest) GetContainerId() string { func (x *FindContainerRequest) GetContainerId() string {
@@ -157,7 +211,7 @@ type FindContainerResponse struct {
func (x *FindContainerResponse) Reset() { func (x *FindContainerResponse) Reset() {
*x = FindContainerResponse{} *x = FindContainerResponse{}
mi := &file_rpc_proto_msgTypes[3] mi := &file_rpc_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -169,7 +223,7 @@ func (x *FindContainerResponse) String() string {
func (*FindContainerResponse) ProtoMessage() {} func (*FindContainerResponse) ProtoMessage() {}
func (x *FindContainerResponse) ProtoReflect() protoreflect.Message { func (x *FindContainerResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[3] mi := &file_rpc_proto_msgTypes[4]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -182,7 +236,7 @@ func (x *FindContainerResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use FindContainerResponse.ProtoReflect.Descriptor instead. // Deprecated: Use FindContainerResponse.ProtoReflect.Descriptor instead.
func (*FindContainerResponse) Descriptor() ([]byte, []int) { func (*FindContainerResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{3} return file_rpc_proto_rawDescGZIP(), []int{4}
} }
func (x *FindContainerResponse) GetContainer() *Container { func (x *FindContainerResponse) GetContainer() *Container {
@@ -204,7 +258,7 @@ type StreamLogsRequest struct {
func (x *StreamLogsRequest) Reset() { func (x *StreamLogsRequest) Reset() {
*x = StreamLogsRequest{} *x = StreamLogsRequest{}
mi := &file_rpc_proto_msgTypes[4] mi := &file_rpc_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -216,7 +270,7 @@ func (x *StreamLogsRequest) String() string {
func (*StreamLogsRequest) ProtoMessage() {} func (*StreamLogsRequest) ProtoMessage() {}
func (x *StreamLogsRequest) ProtoReflect() protoreflect.Message { func (x *StreamLogsRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[4] mi := &file_rpc_proto_msgTypes[5]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -229,7 +283,7 @@ func (x *StreamLogsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamLogsRequest.ProtoReflect.Descriptor instead. // Deprecated: Use StreamLogsRequest.ProtoReflect.Descriptor instead.
func (*StreamLogsRequest) Descriptor() ([]byte, []int) { func (*StreamLogsRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{4} return file_rpc_proto_rawDescGZIP(), []int{5}
} }
func (x *StreamLogsRequest) GetContainerId() string { func (x *StreamLogsRequest) GetContainerId() string {
@@ -263,7 +317,7 @@ type StreamLogsResponse struct {
func (x *StreamLogsResponse) Reset() { func (x *StreamLogsResponse) Reset() {
*x = StreamLogsResponse{} *x = StreamLogsResponse{}
mi := &file_rpc_proto_msgTypes[5] mi := &file_rpc_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -275,7 +329,7 @@ func (x *StreamLogsResponse) String() string {
func (*StreamLogsResponse) ProtoMessage() {} func (*StreamLogsResponse) ProtoMessage() {}
func (x *StreamLogsResponse) ProtoReflect() protoreflect.Message { func (x *StreamLogsResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[5] mi := &file_rpc_proto_msgTypes[6]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -288,7 +342,7 @@ func (x *StreamLogsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamLogsResponse.ProtoReflect.Descriptor instead. // Deprecated: Use StreamLogsResponse.ProtoReflect.Descriptor instead.
func (*StreamLogsResponse) Descriptor() ([]byte, []int) { func (*StreamLogsResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{5} return file_rpc_proto_rawDescGZIP(), []int{6}
} }
func (x *StreamLogsResponse) GetEvent() *LogEvent { func (x *StreamLogsResponse) GetEvent() *LogEvent {
@@ -311,7 +365,7 @@ type LogsBetweenDatesRequest struct {
func (x *LogsBetweenDatesRequest) Reset() { func (x *LogsBetweenDatesRequest) Reset() {
*x = LogsBetweenDatesRequest{} *x = LogsBetweenDatesRequest{}
mi := &file_rpc_proto_msgTypes[6] mi := &file_rpc_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -323,7 +377,7 @@ func (x *LogsBetweenDatesRequest) String() string {
func (*LogsBetweenDatesRequest) ProtoMessage() {} func (*LogsBetweenDatesRequest) ProtoMessage() {}
func (x *LogsBetweenDatesRequest) ProtoReflect() protoreflect.Message { func (x *LogsBetweenDatesRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[6] mi := &file_rpc_proto_msgTypes[7]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -336,7 +390,7 @@ func (x *LogsBetweenDatesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use LogsBetweenDatesRequest.ProtoReflect.Descriptor instead. // Deprecated: Use LogsBetweenDatesRequest.ProtoReflect.Descriptor instead.
func (*LogsBetweenDatesRequest) Descriptor() ([]byte, []int) { func (*LogsBetweenDatesRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{6} return file_rpc_proto_rawDescGZIP(), []int{7}
} }
func (x *LogsBetweenDatesRequest) GetContainerId() string { func (x *LogsBetweenDatesRequest) GetContainerId() string {
@@ -380,7 +434,7 @@ type StreamRawBytesRequest struct {
func (x *StreamRawBytesRequest) Reset() { func (x *StreamRawBytesRequest) Reset() {
*x = StreamRawBytesRequest{} *x = StreamRawBytesRequest{}
mi := &file_rpc_proto_msgTypes[7] mi := &file_rpc_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -392,7 +446,7 @@ func (x *StreamRawBytesRequest) String() string {
func (*StreamRawBytesRequest) ProtoMessage() {} func (*StreamRawBytesRequest) ProtoMessage() {}
func (x *StreamRawBytesRequest) ProtoReflect() protoreflect.Message { func (x *StreamRawBytesRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[7] mi := &file_rpc_proto_msgTypes[8]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -405,7 +459,7 @@ func (x *StreamRawBytesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamRawBytesRequest.ProtoReflect.Descriptor instead. // Deprecated: Use StreamRawBytesRequest.ProtoReflect.Descriptor instead.
func (*StreamRawBytesRequest) Descriptor() ([]byte, []int) { func (*StreamRawBytesRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{7} return file_rpc_proto_rawDescGZIP(), []int{8}
} }
func (x *StreamRawBytesRequest) GetContainerId() string { func (x *StreamRawBytesRequest) GetContainerId() string {
@@ -446,7 +500,7 @@ type StreamRawBytesResponse struct {
func (x *StreamRawBytesResponse) Reset() { func (x *StreamRawBytesResponse) Reset() {
*x = StreamRawBytesResponse{} *x = StreamRawBytesResponse{}
mi := &file_rpc_proto_msgTypes[8] mi := &file_rpc_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -458,7 +512,7 @@ func (x *StreamRawBytesResponse) String() string {
func (*StreamRawBytesResponse) ProtoMessage() {} func (*StreamRawBytesResponse) ProtoMessage() {}
func (x *StreamRawBytesResponse) ProtoReflect() protoreflect.Message { func (x *StreamRawBytesResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[8] mi := &file_rpc_proto_msgTypes[9]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -471,7 +525,7 @@ func (x *StreamRawBytesResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamRawBytesResponse.ProtoReflect.Descriptor instead. // Deprecated: Use StreamRawBytesResponse.ProtoReflect.Descriptor instead.
func (*StreamRawBytesResponse) Descriptor() ([]byte, []int) { func (*StreamRawBytesResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{8} return file_rpc_proto_rawDescGZIP(), []int{9}
} }
func (x *StreamRawBytesResponse) GetData() []byte { func (x *StreamRawBytesResponse) GetData() []byte {
@@ -489,7 +543,7 @@ type StreamEventsRequest struct {
func (x *StreamEventsRequest) Reset() { func (x *StreamEventsRequest) Reset() {
*x = StreamEventsRequest{} *x = StreamEventsRequest{}
mi := &file_rpc_proto_msgTypes[9] mi := &file_rpc_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -501,7 +555,7 @@ func (x *StreamEventsRequest) String() string {
func (*StreamEventsRequest) ProtoMessage() {} func (*StreamEventsRequest) ProtoMessage() {}
func (x *StreamEventsRequest) ProtoReflect() protoreflect.Message { func (x *StreamEventsRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[9] mi := &file_rpc_proto_msgTypes[10]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -514,7 +568,7 @@ func (x *StreamEventsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamEventsRequest.ProtoReflect.Descriptor instead. // Deprecated: Use StreamEventsRequest.ProtoReflect.Descriptor instead.
func (*StreamEventsRequest) Descriptor() ([]byte, []int) { func (*StreamEventsRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{9} return file_rpc_proto_rawDescGZIP(), []int{10}
} }
type StreamEventsResponse struct { type StreamEventsResponse struct {
@@ -527,7 +581,7 @@ type StreamEventsResponse struct {
func (x *StreamEventsResponse) Reset() { func (x *StreamEventsResponse) Reset() {
*x = StreamEventsResponse{} *x = StreamEventsResponse{}
mi := &file_rpc_proto_msgTypes[10] mi := &file_rpc_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -539,7 +593,7 @@ func (x *StreamEventsResponse) String() string {
func (*StreamEventsResponse) ProtoMessage() {} func (*StreamEventsResponse) ProtoMessage() {}
func (x *StreamEventsResponse) ProtoReflect() protoreflect.Message { func (x *StreamEventsResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[10] mi := &file_rpc_proto_msgTypes[11]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -552,7 +606,7 @@ func (x *StreamEventsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamEventsResponse.ProtoReflect.Descriptor instead. // Deprecated: Use StreamEventsResponse.ProtoReflect.Descriptor instead.
func (*StreamEventsResponse) Descriptor() ([]byte, []int) { func (*StreamEventsResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{10} return file_rpc_proto_rawDescGZIP(), []int{11}
} }
func (x *StreamEventsResponse) GetEvent() *ContainerEvent { func (x *StreamEventsResponse) GetEvent() *ContainerEvent {
@@ -570,7 +624,7 @@ type StreamStatsRequest struct {
func (x *StreamStatsRequest) Reset() { func (x *StreamStatsRequest) Reset() {
*x = StreamStatsRequest{} *x = StreamStatsRequest{}
mi := &file_rpc_proto_msgTypes[11] mi := &file_rpc_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -582,7 +636,7 @@ func (x *StreamStatsRequest) String() string {
func (*StreamStatsRequest) ProtoMessage() {} func (*StreamStatsRequest) ProtoMessage() {}
func (x *StreamStatsRequest) ProtoReflect() protoreflect.Message { func (x *StreamStatsRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[11] mi := &file_rpc_proto_msgTypes[12]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -595,7 +649,7 @@ func (x *StreamStatsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamStatsRequest.ProtoReflect.Descriptor instead. // Deprecated: Use StreamStatsRequest.ProtoReflect.Descriptor instead.
func (*StreamStatsRequest) Descriptor() ([]byte, []int) { func (*StreamStatsRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{11} return file_rpc_proto_rawDescGZIP(), []int{12}
} }
type StreamStatsResponse struct { type StreamStatsResponse struct {
@@ -608,7 +662,7 @@ type StreamStatsResponse struct {
func (x *StreamStatsResponse) Reset() { func (x *StreamStatsResponse) Reset() {
*x = StreamStatsResponse{} *x = StreamStatsResponse{}
mi := &file_rpc_proto_msgTypes[12] mi := &file_rpc_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -620,7 +674,7 @@ func (x *StreamStatsResponse) String() string {
func (*StreamStatsResponse) ProtoMessage() {} func (*StreamStatsResponse) ProtoMessage() {}
func (x *StreamStatsResponse) ProtoReflect() protoreflect.Message { func (x *StreamStatsResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[12] mi := &file_rpc_proto_msgTypes[13]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -633,7 +687,7 @@ func (x *StreamStatsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamStatsResponse.ProtoReflect.Descriptor instead. // Deprecated: Use StreamStatsResponse.ProtoReflect.Descriptor instead.
func (*StreamStatsResponse) Descriptor() ([]byte, []int) { func (*StreamStatsResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{12} return file_rpc_proto_rawDescGZIP(), []int{13}
} }
func (x *StreamStatsResponse) GetStat() *ContainerStat { func (x *StreamStatsResponse) GetStat() *ContainerStat {
@@ -651,7 +705,7 @@ type HostInfoRequest struct {
func (x *HostInfoRequest) Reset() { func (x *HostInfoRequest) Reset() {
*x = HostInfoRequest{} *x = HostInfoRequest{}
mi := &file_rpc_proto_msgTypes[13] mi := &file_rpc_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -663,7 +717,7 @@ func (x *HostInfoRequest) String() string {
func (*HostInfoRequest) ProtoMessage() {} func (*HostInfoRequest) ProtoMessage() {}
func (x *HostInfoRequest) ProtoReflect() protoreflect.Message { func (x *HostInfoRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[13] mi := &file_rpc_proto_msgTypes[14]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -676,7 +730,7 @@ func (x *HostInfoRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use HostInfoRequest.ProtoReflect.Descriptor instead. // Deprecated: Use HostInfoRequest.ProtoReflect.Descriptor instead.
func (*HostInfoRequest) Descriptor() ([]byte, []int) { func (*HostInfoRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{13} return file_rpc_proto_rawDescGZIP(), []int{14}
} }
type HostInfoResponse struct { type HostInfoResponse struct {
@@ -689,7 +743,7 @@ type HostInfoResponse struct {
func (x *HostInfoResponse) Reset() { func (x *HostInfoResponse) Reset() {
*x = HostInfoResponse{} *x = HostInfoResponse{}
mi := &file_rpc_proto_msgTypes[14] mi := &file_rpc_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -701,7 +755,7 @@ func (x *HostInfoResponse) String() string {
func (*HostInfoResponse) ProtoMessage() {} func (*HostInfoResponse) ProtoMessage() {}
func (x *HostInfoResponse) ProtoReflect() protoreflect.Message { func (x *HostInfoResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[14] mi := &file_rpc_proto_msgTypes[15]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -714,7 +768,7 @@ func (x *HostInfoResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use HostInfoResponse.ProtoReflect.Descriptor instead. // Deprecated: Use HostInfoResponse.ProtoReflect.Descriptor instead.
func (*HostInfoResponse) Descriptor() ([]byte, []int) { func (*HostInfoResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{14} return file_rpc_proto_rawDescGZIP(), []int{15}
} }
func (x *HostInfoResponse) GetHost() *Host { func (x *HostInfoResponse) GetHost() *Host {
@@ -732,7 +786,7 @@ type StreamContainerStartedRequest struct {
func (x *StreamContainerStartedRequest) Reset() { func (x *StreamContainerStartedRequest) Reset() {
*x = StreamContainerStartedRequest{} *x = StreamContainerStartedRequest{}
mi := &file_rpc_proto_msgTypes[15] mi := &file_rpc_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -744,7 +798,7 @@ func (x *StreamContainerStartedRequest) String() string {
func (*StreamContainerStartedRequest) ProtoMessage() {} func (*StreamContainerStartedRequest) ProtoMessage() {}
func (x *StreamContainerStartedRequest) ProtoReflect() protoreflect.Message { func (x *StreamContainerStartedRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[15] mi := &file_rpc_proto_msgTypes[16]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -757,7 +811,7 @@ func (x *StreamContainerStartedRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamContainerStartedRequest.ProtoReflect.Descriptor instead. // Deprecated: Use StreamContainerStartedRequest.ProtoReflect.Descriptor instead.
func (*StreamContainerStartedRequest) Descriptor() ([]byte, []int) { func (*StreamContainerStartedRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{15} return file_rpc_proto_rawDescGZIP(), []int{16}
} }
type StreamContainerStartedResponse struct { type StreamContainerStartedResponse struct {
@@ -770,7 +824,7 @@ type StreamContainerStartedResponse struct {
func (x *StreamContainerStartedResponse) Reset() { func (x *StreamContainerStartedResponse) Reset() {
*x = StreamContainerStartedResponse{} *x = StreamContainerStartedResponse{}
mi := &file_rpc_proto_msgTypes[16] mi := &file_rpc_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -782,7 +836,7 @@ func (x *StreamContainerStartedResponse) String() string {
func (*StreamContainerStartedResponse) ProtoMessage() {} func (*StreamContainerStartedResponse) ProtoMessage() {}
func (x *StreamContainerStartedResponse) ProtoReflect() protoreflect.Message { func (x *StreamContainerStartedResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[16] mi := &file_rpc_proto_msgTypes[17]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -795,7 +849,7 @@ func (x *StreamContainerStartedResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use StreamContainerStartedResponse.ProtoReflect.Descriptor instead. // Deprecated: Use StreamContainerStartedResponse.ProtoReflect.Descriptor instead.
func (*StreamContainerStartedResponse) Descriptor() ([]byte, []int) { func (*StreamContainerStartedResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{16} return file_rpc_proto_rawDescGZIP(), []int{17}
} }
func (x *StreamContainerStartedResponse) GetContainer() *Container { func (x *StreamContainerStartedResponse) GetContainer() *Container {
@@ -816,7 +870,7 @@ type ContainerActionRequest struct {
func (x *ContainerActionRequest) Reset() { func (x *ContainerActionRequest) Reset() {
*x = ContainerActionRequest{} *x = ContainerActionRequest{}
mi := &file_rpc_proto_msgTypes[17] mi := &file_rpc_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -828,7 +882,7 @@ func (x *ContainerActionRequest) String() string {
func (*ContainerActionRequest) ProtoMessage() {} func (*ContainerActionRequest) ProtoMessage() {}
func (x *ContainerActionRequest) ProtoReflect() protoreflect.Message { func (x *ContainerActionRequest) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[17] mi := &file_rpc_proto_msgTypes[18]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -841,7 +895,7 @@ func (x *ContainerActionRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ContainerActionRequest.ProtoReflect.Descriptor instead. // Deprecated: Use ContainerActionRequest.ProtoReflect.Descriptor instead.
func (*ContainerActionRequest) Descriptor() ([]byte, []int) { func (*ContainerActionRequest) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{17} return file_rpc_proto_rawDescGZIP(), []int{18}
} }
func (x *ContainerActionRequest) GetContainerId() string { func (x *ContainerActionRequest) GetContainerId() string {
@@ -866,7 +920,7 @@ type ContainerActionResponse struct {
func (x *ContainerActionResponse) Reset() { func (x *ContainerActionResponse) Reset() {
*x = ContainerActionResponse{} *x = ContainerActionResponse{}
mi := &file_rpc_proto_msgTypes[18] mi := &file_rpc_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -878,7 +932,7 @@ func (x *ContainerActionResponse) String() string {
func (*ContainerActionResponse) ProtoMessage() {} func (*ContainerActionResponse) ProtoMessage() {}
func (x *ContainerActionResponse) ProtoReflect() protoreflect.Message { func (x *ContainerActionResponse) ProtoReflect() protoreflect.Message {
mi := &file_rpc_proto_msgTypes[18] mi := &file_rpc_proto_msgTypes[19]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -891,7 +945,7 @@ func (x *ContainerActionResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ContainerActionResponse.ProtoReflect.Descriptor instead. // Deprecated: Use ContainerActionResponse.ProtoReflect.Descriptor instead.
func (*ContainerActionResponse) Descriptor() ([]byte, []int) { func (*ContainerActionResponse) Descriptor() ([]byte, []int) {
return file_rpc_proto_rawDescGZIP(), []int{18} return file_rpc_proto_rawDescGZIP(), []int{19}
} }
var File_rpc_proto protoreflect.FileDescriptor var File_rpc_proto protoreflect.FileDescriptor
@@ -901,150 +955,163 @@ var file_rpc_proto_rawDesc = []byte{
0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74,
0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4d, 0x0a, 0x16, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a,
0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74,
0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x38, 0x0a, 0x14, 0x46, 0x65, 0x72, 0x1a, 0x53, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72,
0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65,
0x6e, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4a, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76, 0x61,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x28, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x65, 0x61,
0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c,
0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x4d, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x72, 0x22, 0x89, 0x01, 0x0a, 0x11, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x63,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73,
0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x22, 0x38, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74,
0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63,
0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4a, 0x0a, 0x15, 0x46, 0x69,
0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x6f, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e,
0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xc1, 0x01, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x89, 0x01, 0x0a, 0x11, 0x53, 0x74, 0x72, 0x65, 0x61,
0x0a, 0x17, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b,
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18,
0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x65, 0x73, 0x22, 0x3e, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x12, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e,
0x20, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x75, 0x66, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65,
0x73, 0x22, 0xbf, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x6e, 0x74, 0x22, 0xc1, 0x01, 0x0a, 0x17, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65,
0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20,
0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64,
0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x69, 0x6e,
0x30, 0x0a, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x75,
0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x6e, 0x74, 0x69, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79,
0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61,
0x70, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0xbf, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61,
0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18,
0x61, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x46, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x2e, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73,
0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x03, 0x20,
0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x22, 0x14, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x42, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x05, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x74, 0x72,
0x04, 0x73, 0x74, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x53, 0x74, 0x61, 0x74, 0x52, 0x04, 0x73, 0x74, 0x61, 0x74, 0x22, 0x11, 0x0a, 0x0f, 0x48, 0x6f, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x36, 0x0a, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x10, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x46, 0x0a,
0x65, 0x12, 0x22, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73,
0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01,
0x04, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x1f, 0x0a, 0x1d, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x1e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x42, 0x0a, 0x13, 0x53,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x73, 0x74, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x6d, 0x0a, 0x16, 0x43, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x52, 0x04, 0x73, 0x74, 0x61, 0x74, 0x22,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x11, 0x0a, 0x0f, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x74, 0x22, 0x36, 0x0a, 0x10, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65,
0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x1f, 0x0a, 0x1d, 0x53, 0x74,
0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61,
0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x19, 0x0a, 0x17, 0x43, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x1e, 0x53,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xeb, 0x06, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x22, 0x6d, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f,
0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0d, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x06,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x70,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x12,
0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f,
0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x57,
0x0a, 0x10, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74,
0x65, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x6f,
0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x57, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x79,
0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42,
0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01,
0x12, 0x51, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73,
0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x30, 0x01, 0x12, 0x4e, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61,
0x74, 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x30, 0x01, 0x12, 0x6f, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x27, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f,
0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x19, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69,
0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xeb, 0x06, 0x0a, 0x0c, 0x41,
0x65, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x0e, 0x4c,
0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x52, 0x0a, 0x0d, 0x46, 0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46,
0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46,
0x69, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x30, 0x01, 0x12, 0x57, 0x0a, 0x10, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65,
0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x44, 0x61,
0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x6f, 0x67, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x57, 0x0a, 0x0e,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1f,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x51, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45,
0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x4e, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x6f, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74,
0x65, 0x64, 0x12, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61,
0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x08, 0x48, 0x6f, 0x73,
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x48, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x48, 0x6f, 0x73, 0x74,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58,
0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@@ -1059,74 +1126,78 @@ func file_rpc_proto_rawDescGZIP() []byte {
return file_rpc_proto_rawDescData return file_rpc_proto_rawDescData
} }
var file_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
var file_rpc_proto_goTypes = []any{ var file_rpc_proto_goTypes = []any{
(*ListContainersRequest)(nil), // 0: protobuf.ListContainersRequest (*ListContainersRequest)(nil), // 0: protobuf.ListContainersRequest
(*ListContainersResponse)(nil), // 1: protobuf.ListContainersResponse (*RepeatedString)(nil), // 1: protobuf.RepeatedString
(*FindContainerRequest)(nil), // 2: protobuf.FindContainerRequest (*ListContainersResponse)(nil), // 2: protobuf.ListContainersResponse
(*FindContainerResponse)(nil), // 3: protobuf.FindContainerResponse (*FindContainerRequest)(nil), // 3: protobuf.FindContainerRequest
(*StreamLogsRequest)(nil), // 4: protobuf.StreamLogsRequest (*FindContainerResponse)(nil), // 4: protobuf.FindContainerResponse
(*StreamLogsResponse)(nil), // 5: protobuf.StreamLogsResponse (*StreamLogsRequest)(nil), // 5: protobuf.StreamLogsRequest
(*LogsBetweenDatesRequest)(nil), // 6: protobuf.LogsBetweenDatesRequest (*StreamLogsResponse)(nil), // 6: protobuf.StreamLogsResponse
(*StreamRawBytesRequest)(nil), // 7: protobuf.StreamRawBytesRequest (*LogsBetweenDatesRequest)(nil), // 7: protobuf.LogsBetweenDatesRequest
(*StreamRawBytesResponse)(nil), // 8: protobuf.StreamRawBytesResponse (*StreamRawBytesRequest)(nil), // 8: protobuf.StreamRawBytesRequest
(*StreamEventsRequest)(nil), // 9: protobuf.StreamEventsRequest (*StreamRawBytesResponse)(nil), // 9: protobuf.StreamRawBytesResponse
(*StreamEventsResponse)(nil), // 10: protobuf.StreamEventsResponse (*StreamEventsRequest)(nil), // 10: protobuf.StreamEventsRequest
(*StreamStatsRequest)(nil), // 11: protobuf.StreamStatsRequest (*StreamEventsResponse)(nil), // 11: protobuf.StreamEventsResponse
(*StreamStatsResponse)(nil), // 12: protobuf.StreamStatsResponse (*StreamStatsRequest)(nil), // 12: protobuf.StreamStatsRequest
(*HostInfoRequest)(nil), // 13: protobuf.HostInfoRequest (*StreamStatsResponse)(nil), // 13: protobuf.StreamStatsResponse
(*HostInfoResponse)(nil), // 14: protobuf.HostInfoResponse (*HostInfoRequest)(nil), // 14: protobuf.HostInfoRequest
(*StreamContainerStartedRequest)(nil), // 15: protobuf.StreamContainerStartedRequest (*HostInfoResponse)(nil), // 15: protobuf.HostInfoResponse
(*StreamContainerStartedResponse)(nil), // 16: protobuf.StreamContainerStartedResponse (*StreamContainerStartedRequest)(nil), // 16: protobuf.StreamContainerStartedRequest
(*ContainerActionRequest)(nil), // 17: protobuf.ContainerActionRequest (*StreamContainerStartedResponse)(nil), // 17: protobuf.StreamContainerStartedResponse
(*ContainerActionResponse)(nil), // 18: protobuf.ContainerActionResponse (*ContainerActionRequest)(nil), // 18: protobuf.ContainerActionRequest
(*Container)(nil), // 19: protobuf.Container (*ContainerActionResponse)(nil), // 19: protobuf.ContainerActionResponse
(*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp nil, // 20: protobuf.ListContainersRequest.FilterEntry
(*LogEvent)(nil), // 21: protobuf.LogEvent (*Container)(nil), // 21: protobuf.Container
(*ContainerEvent)(nil), // 22: protobuf.ContainerEvent (*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp
(*ContainerStat)(nil), // 23: protobuf.ContainerStat (*LogEvent)(nil), // 23: protobuf.LogEvent
(*Host)(nil), // 24: protobuf.Host (*ContainerEvent)(nil), // 24: protobuf.ContainerEvent
(ContainerAction)(0), // 25: protobuf.ContainerAction (*ContainerStat)(nil), // 25: protobuf.ContainerStat
(*Host)(nil), // 26: protobuf.Host
(ContainerAction)(0), // 27: protobuf.ContainerAction
} }
var file_rpc_proto_depIdxs = []int32{ var file_rpc_proto_depIdxs = []int32{
19, // 0: protobuf.ListContainersResponse.containers:type_name -> protobuf.Container 20, // 0: protobuf.ListContainersRequest.filter:type_name -> protobuf.ListContainersRequest.FilterEntry
19, // 1: protobuf.FindContainerResponse.container:type_name -> protobuf.Container 21, // 1: protobuf.ListContainersResponse.containers:type_name -> protobuf.Container
20, // 2: protobuf.StreamLogsRequest.since:type_name -> google.protobuf.Timestamp 21, // 2: protobuf.FindContainerResponse.container:type_name -> protobuf.Container
21, // 3: protobuf.StreamLogsResponse.event:type_name -> protobuf.LogEvent 22, // 3: protobuf.StreamLogsRequest.since:type_name -> google.protobuf.Timestamp
20, // 4: protobuf.LogsBetweenDatesRequest.since:type_name -> google.protobuf.Timestamp 23, // 4: protobuf.StreamLogsResponse.event:type_name -> protobuf.LogEvent
20, // 5: protobuf.LogsBetweenDatesRequest.until:type_name -> google.protobuf.Timestamp 22, // 5: protobuf.LogsBetweenDatesRequest.since:type_name -> google.protobuf.Timestamp
20, // 6: protobuf.StreamRawBytesRequest.since:type_name -> google.protobuf.Timestamp 22, // 6: protobuf.LogsBetweenDatesRequest.until:type_name -> google.protobuf.Timestamp
20, // 7: protobuf.StreamRawBytesRequest.until:type_name -> google.protobuf.Timestamp 22, // 7: protobuf.StreamRawBytesRequest.since:type_name -> google.protobuf.Timestamp
22, // 8: protobuf.StreamEventsResponse.event:type_name -> protobuf.ContainerEvent 22, // 8: protobuf.StreamRawBytesRequest.until:type_name -> google.protobuf.Timestamp
23, // 9: protobuf.StreamStatsResponse.stat:type_name -> protobuf.ContainerStat 24, // 9: protobuf.StreamEventsResponse.event:type_name -> protobuf.ContainerEvent
24, // 10: protobuf.HostInfoResponse.host:type_name -> protobuf.Host 25, // 10: protobuf.StreamStatsResponse.stat:type_name -> protobuf.ContainerStat
19, // 11: protobuf.StreamContainerStartedResponse.container:type_name -> protobuf.Container 26, // 11: protobuf.HostInfoResponse.host:type_name -> protobuf.Host
25, // 12: protobuf.ContainerActionRequest.action:type_name -> protobuf.ContainerAction 21, // 12: protobuf.StreamContainerStartedResponse.container:type_name -> protobuf.Container
0, // 13: protobuf.AgentService.ListContainers:input_type -> protobuf.ListContainersRequest 27, // 13: protobuf.ContainerActionRequest.action:type_name -> protobuf.ContainerAction
2, // 14: protobuf.AgentService.FindContainer:input_type -> protobuf.FindContainerRequest 1, // 14: protobuf.ListContainersRequest.FilterEntry.value:type_name -> protobuf.RepeatedString
4, // 15: protobuf.AgentService.StreamLogs:input_type -> protobuf.StreamLogsRequest 0, // 15: protobuf.AgentService.ListContainers:input_type -> protobuf.ListContainersRequest
6, // 16: protobuf.AgentService.LogsBetweenDates:input_type -> protobuf.LogsBetweenDatesRequest 3, // 16: protobuf.AgentService.FindContainer:input_type -> protobuf.FindContainerRequest
7, // 17: protobuf.AgentService.StreamRawBytes:input_type -> protobuf.StreamRawBytesRequest 5, // 17: protobuf.AgentService.StreamLogs:input_type -> protobuf.StreamLogsRequest
9, // 18: protobuf.AgentService.StreamEvents:input_type -> protobuf.StreamEventsRequest 7, // 18: protobuf.AgentService.LogsBetweenDates:input_type -> protobuf.LogsBetweenDatesRequest
11, // 19: protobuf.AgentService.StreamStats:input_type -> protobuf.StreamStatsRequest 8, // 19: protobuf.AgentService.StreamRawBytes:input_type -> protobuf.StreamRawBytesRequest
15, // 20: protobuf.AgentService.StreamContainerStarted:input_type -> protobuf.StreamContainerStartedRequest 10, // 20: protobuf.AgentService.StreamEvents:input_type -> protobuf.StreamEventsRequest
13, // 21: protobuf.AgentService.HostInfo:input_type -> protobuf.HostInfoRequest 12, // 21: protobuf.AgentService.StreamStats:input_type -> protobuf.StreamStatsRequest
17, // 22: protobuf.AgentService.ContainerAction:input_type -> protobuf.ContainerActionRequest 16, // 22: protobuf.AgentService.StreamContainerStarted:input_type -> protobuf.StreamContainerStartedRequest
1, // 23: protobuf.AgentService.ListContainers:output_type -> protobuf.ListContainersResponse 14, // 23: protobuf.AgentService.HostInfo:input_type -> protobuf.HostInfoRequest
3, // 24: protobuf.AgentService.FindContainer:output_type -> protobuf.FindContainerResponse 18, // 24: protobuf.AgentService.ContainerAction:input_type -> protobuf.ContainerActionRequest
5, // 25: protobuf.AgentService.StreamLogs:output_type -> protobuf.StreamLogsResponse 2, // 25: protobuf.AgentService.ListContainers:output_type -> protobuf.ListContainersResponse
5, // 26: protobuf.AgentService.LogsBetweenDates:output_type -> protobuf.StreamLogsResponse 4, // 26: protobuf.AgentService.FindContainer:output_type -> protobuf.FindContainerResponse
8, // 27: protobuf.AgentService.StreamRawBytes:output_type -> protobuf.StreamRawBytesResponse 6, // 27: protobuf.AgentService.StreamLogs:output_type -> protobuf.StreamLogsResponse
10, // 28: protobuf.AgentService.StreamEvents:output_type -> protobuf.StreamEventsResponse 6, // 28: protobuf.AgentService.LogsBetweenDates:output_type -> protobuf.StreamLogsResponse
12, // 29: protobuf.AgentService.StreamStats:output_type -> protobuf.StreamStatsResponse 9, // 29: protobuf.AgentService.StreamRawBytes:output_type -> protobuf.StreamRawBytesResponse
16, // 30: protobuf.AgentService.StreamContainerStarted:output_type -> protobuf.StreamContainerStartedResponse 11, // 30: protobuf.AgentService.StreamEvents:output_type -> protobuf.StreamEventsResponse
14, // 31: protobuf.AgentService.HostInfo:output_type -> protobuf.HostInfoResponse 13, // 31: protobuf.AgentService.StreamStats:output_type -> protobuf.StreamStatsResponse
18, // 32: protobuf.AgentService.ContainerAction:output_type -> protobuf.ContainerActionResponse 17, // 32: protobuf.AgentService.StreamContainerStarted:output_type -> protobuf.StreamContainerStartedResponse
23, // [23:33] is the sub-list for method output_type 15, // 33: protobuf.AgentService.HostInfo:output_type -> protobuf.HostInfoResponse
13, // [13:23] is the sub-list for method input_type 19, // 34: protobuf.AgentService.ContainerAction:output_type -> protobuf.ContainerActionResponse
13, // [13:13] is the sub-list for extension type_name 25, // [25:35] is the sub-list for method output_type
13, // [13:13] is the sub-list for extension extendee 15, // [15:25] is the sub-list for method input_type
0, // [0:13] is the sub-list for field type_name 15, // [15:15] is the sub-list for extension type_name
15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
} }
func init() { file_rpc_proto_init() } func init() { file_rpc_proto_init() }
@@ -1141,7 +1212,7 @@ func file_rpc_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_rpc_proto_rawDesc, RawDescriptor: file_rpc_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 19, NumMessages: 21,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT. // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions: // versions:
// - protoc-gen-go-grpc v1.5.1 // - protoc-gen-go-grpc v1.5.1
// - protoc v5.28.3 // - protoc v5.29.1
// source: rpc.proto // source: rpc.proto
package pb package pb

View File

@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.35.1
// protoc v5.28.3 // protoc v5.29.1
// source: types.proto // source: types.proto
package pb package pb

View File

@@ -32,12 +32,12 @@ type server struct {
pb.UnimplementedAgentServiceServer pb.UnimplementedAgentServiceServer
} }
func newServer(client docker.Client, dozzleVersion string) pb.AgentServiceServer { func newServer(client docker.Client, dozzleVersion string, filter docker.ContainerFilter) pb.AgentServiceServer {
return &server{ return &server{
client: client, client: client,
version: dozzleVersion, version: dozzleVersion,
store: docker.NewContainerStore(context.Background(), client), store: docker.NewContainerStore(context.Background(), client, filter),
} }
} }
@@ -196,7 +196,16 @@ func (s *server) FindContainer(ctx context.Context, in *pb.FindContainerRequest)
} }
func (s *server) ListContainers(ctx context.Context, in *pb.ListContainersRequest) (*pb.ListContainersResponse, error) { func (s *server) ListContainers(ctx context.Context, in *pb.ListContainersRequest) (*pb.ListContainersResponse, error) {
containers, err := s.store.ListContainers() filter := make(docker.ContainerFilter)
if in.GetFilter() != nil {
for k, v := range in.GetFilter() {
for _, vv := range v.GetValues() {
filter[k] = append(filter[k], vv)
}
}
}
containers, err := s.store.ListContainers(filter)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -304,7 +313,7 @@ func (s *server) ContainerAction(ctx context.Context, in *pb.ContainerActionRequ
return &pb.ContainerActionResponse{}, nil return &pb.ContainerActionResponse{}, nil
} }
func NewServer(client docker.Client, certificates tls.Certificate, dozzleVersion string) (*grpc.Server, error) { func NewServer(client docker.Client, certificates tls.Certificate, dozzleVersion string, filter docker.ContainerFilter) (*grpc.Server, error) {
caCertPool := x509.NewCertPool() caCertPool := x509.NewCertPool()
c, err := x509.ParseCertificate(certificates.Certificate[0]) c, err := x509.ParseCertificate(certificates.Certificate[0])
if err != nil { if err != nil {
@@ -323,7 +332,7 @@ func NewServer(client docker.Client, certificates tls.Certificate, dozzleVersion
creds := credentials.NewTLS(tlsConfig) creds := credentials.NewTLS(tlsConfig)
grpcServer := grpc.NewServer(grpc.Creds(creds)) grpcServer := grpc.NewServer(grpc.Creds(creds))
pb.RegisterAgentServiceServer(grpcServer, newServer(client, dozzleVersion)) pb.RegisterAgentServiceServer(grpcServer, newServer(client, dozzleVersion, filter))
return grpcServer, nil return grpcServer, nil
} }

View File

@@ -15,7 +15,6 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/api/types/system" "github.com/docker/docker/api/types/system"
"github.com/docker/docker/client" "github.com/docker/docker/client"
@@ -59,7 +58,7 @@ type DockerCLI interface {
} }
type Client interface { type Client interface {
ListContainers(context.Context) ([]Container, error) ListContainers(context.Context, ContainerFilter) ([]Container, error)
FindContainer(context.Context, string) (Container, error) FindContainer(context.Context, string) (Container, error)
ContainerLogs(context.Context, string, time.Time, StdType) (io.ReadCloser, error) ContainerLogs(context.Context, string, time.Time, StdType) (io.ReadCloser, error)
ContainerEvents(context.Context, chan<- ContainerEvent) error ContainerEvents(context.Context, chan<- ContainerEvent) error
@@ -74,12 +73,11 @@ type Client interface {
type httpClient struct { type httpClient struct {
cli DockerCLI cli DockerCLI
filters filters.Args
host Host host Host
info system.Info info system.Info
} }
func NewClient(cli DockerCLI, filters filters.Args, host Host) Client { func NewClient(cli DockerCLI, host Host) Client {
info, err := cli.Info(context.Background()) info, err := cli.Info(context.Background())
if err != nil { if err != nil {
log.Error().Err(err).Msg("Failed to get docker info") log.Error().Err(err).Msg("Failed to get docker info")
@@ -91,23 +89,13 @@ func NewClient(cli DockerCLI, filters filters.Args, host Host) Client {
return &httpClient{ return &httpClient{
cli: cli, cli: cli,
filters: filters,
host: host, host: host,
info: info, info: info,
} }
} }
// NewClientWithFilters creates a new instance of Client with docker filters // NewClientWithFilters creates a new instance of Client with docker filters
func NewLocalClient(f map[string][]string, hostname string) (Client, error) { func NewLocalClient(hostname string) (Client, error) {
filterArgs := filters.NewArgs()
for key, values := range f {
for _, value := range values {
filterArgs.Add(key, value)
}
}
log.Debug().Interface("filterArgs", filterArgs).Msg("Creating local client")
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil { if err != nil {
@@ -137,19 +125,10 @@ func NewLocalClient(f map[string][]string, hostname string) (Client, error) {
host.Name = hostname host.Name = hostname
} }
return NewClient(cli, filterArgs, host), nil return NewClient(cli, host), nil
} }
func NewRemoteClient(f map[string][]string, host Host) (Client, error) { func NewRemoteClient(host Host) (Client, error) {
filterArgs := filters.NewArgs()
for key, values := range f {
for _, value := range values {
filterArgs.Add(key, value)
}
}
log.Debug().Interface("filterArgs", filterArgs).Msg("Creating remote client")
if host.URL.Scheme != "tcp" { if host.URL.Scheme != "tcp" {
return nil, fmt.Errorf("invalid scheme: %s", host.URL.Scheme) return nil, fmt.Errorf("invalid scheme: %s", host.URL.Scheme)
} }
@@ -175,7 +154,7 @@ func NewRemoteClient(f map[string][]string, host Host) (Client, error) {
host.Type = "remote" host.Type = "remote"
return NewClient(cli, filterArgs, host), nil return NewClient(cli, host), nil
} }
// Finds a container by id, skipping the filters // Finds a container by id, skipping the filters
@@ -202,10 +181,10 @@ func (d *httpClient) ContainerActions(ctx context.Context, action ContainerActio
} }
} }
func (d *httpClient) ListContainers(ctx context.Context) ([]Container, error) { func (d *httpClient) ListContainers(ctx context.Context, filter ContainerFilter) ([]Container, error) {
log.Debug().Interface("filter", d.filters).Str("host", d.host.Name).Msg("Listing containers") log.Debug().Interface("filter", filter).Str("host", d.host.Name).Msg("Listing containers")
containerListOptions := container.ListOptions{ containerListOptions := container.ListOptions{
Filters: d.filters, Filters: filter.asArgs(),
All: true, All: true,
} }
list, err := d.cli.ContainerList(ctx, containerListOptions) list, err := d.cli.ContainerList(ctx, containerListOptions)

View File

@@ -23,18 +23,20 @@ type ContainerStore struct {
connected atomic.Bool connected atomic.Bool
events chan ContainerEvent events chan ContainerEvent
ctx context.Context ctx context.Context
filter ContainerFilter
} }
func NewContainerStore(ctx context.Context, client Client) *ContainerStore { func NewContainerStore(ctx context.Context, client Client, filter ContainerFilter) *ContainerStore {
s := &ContainerStore{ s := &ContainerStore{
containers: xsync.NewMapOf[string, *Container](), containers: xsync.NewMapOf[string, *Container](),
client: client, client: client,
subscribers: xsync.NewMapOf[context.Context, chan<- ContainerEvent](), subscribers: xsync.NewMapOf[context.Context, chan<- ContainerEvent](),
newContainerSubscribers: xsync.NewMapOf[context.Context, chan<- Container](), newContainerSubscribers: xsync.NewMapOf[context.Context, chan<- Container](),
statsCollector: NewStatsCollector(client), statsCollector: NewStatsCollector(client, filter),
wg: sync.WaitGroup{}, wg: sync.WaitGroup{},
events: make(chan ContainerEvent), events: make(chan ContainerEvent),
ctx: ctx, ctx: ctx,
filter: filter,
} }
s.wg.Add(1) s.wg.Add(1)
@@ -62,7 +64,7 @@ func (s *ContainerStore) checkConnectivity() error {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) // 3s is enough to fetch all containers ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) // 3s is enough to fetch all containers
defer cancel() defer cancel()
if containers, err := s.client.ListContainers(ctx); err != nil { if containers, err := s.client.ListContainers(ctx, s.filter); err != nil {
return err return err
} else { } else {
s.containers.Clear() s.containers.Clear()
@@ -103,15 +105,27 @@ func (s *ContainerStore) checkConnectivity() error {
return nil return nil
} }
func (s *ContainerStore) ListContainers() ([]Container, error) { func (s *ContainerStore) ListContainers(filter ContainerFilter) ([]Container, error) {
s.wg.Wait() s.wg.Wait()
if err := s.checkConnectivity(); err != nil { if err := s.checkConnectivity(); err != nil {
return nil, err return nil, err
} }
validContainers, err := s.client.ListContainers(s.ctx, filter)
if err != nil {
return nil, err
}
validIDMap := lo.KeyBy(validContainers, func(item Container) string {
return item.ID
})
containers := make([]Container, 0) containers := make([]Container, 0)
s.containers.Range(func(_ string, c *Container) bool { s.containers.Range(func(_ string, c *Container) bool {
if _, ok := validIDMap[c.ID]; ok {
containers = append(containers, *c) containers = append(containers, *c)
}
return true return true
}) })
@@ -181,7 +195,7 @@ func (s *ContainerStore) init() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
if container, err := s.client.FindContainer(ctx, event.ActorID); err == nil { if container, err := s.client.FindContainer(ctx, event.ActorID); err == nil {
list, _ := s.client.ListContainers(ctx) list, _ := s.client.ListContainers(ctx, s.filter)
// make sure the container is in the list of containers when using filter // make sure the container is in the list of containers when using filter
valid := lo.ContainsBy(list, func(item Container) bool { valid := lo.ContainsBy(list, func(item Container) bool {

View File

@@ -21,16 +21,18 @@ type StatsCollector struct {
timer *time.Timer timer *time.Timer
mu sync.Mutex mu sync.Mutex
totalStarted atomic.Int32 totalStarted atomic.Int32
filter ContainerFilter
} }
var timeToStop = 6 * time.Hour var timeToStop = 6 * time.Hour
func NewStatsCollector(client Client) *StatsCollector { func NewStatsCollector(client Client, filter ContainerFilter) *StatsCollector {
return &StatsCollector{ return &StatsCollector{
stream: make(chan ContainerStat), stream: make(chan ContainerStat),
subscribers: xsync.NewMapOf[context.Context, chan<- ContainerStat](), subscribers: xsync.NewMapOf[context.Context, chan<- ContainerStat](),
client: client, client: client,
cancelers: xsync.NewMapOf[string, context.CancelFunc](), cancelers: xsync.NewMapOf[string, context.CancelFunc](),
filter: filter,
} }
} }
@@ -98,7 +100,7 @@ func (sc *StatsCollector) Start(parentCtx context.Context) bool {
sc.mu.Unlock() sc.mu.Unlock()
timeoutCtx, cancel := context.WithTimeout(parentCtx, 3*time.Second) // 3 seconds to list containers is hard limit timeoutCtx, cancel := context.WithTimeout(parentCtx, 3*time.Second) // 3 seconds to list containers is hard limit
if containers, err := sc.client.ListContainers(timeoutCtx); err == nil { if containers, err := sc.client.ListContainers(timeoutCtx, sc.filter); err == nil {
for _, c := range containers { for _, c := range containers {
if c.State == "running" { if c.State == "running" {
go streamStats(ctx, sc, c.ID) go streamStats(ctx, sc, c.ID)

View File

@@ -3,9 +3,11 @@ package docker
import ( import (
"fmt" "fmt"
"math" "math"
"strings"
"time" "time"
"github.com/amir20/dozzle/internal/utils" "github.com/amir20/dozzle/internal/utils"
"github.com/docker/docker/api/types/filters"
) )
// Container represents an internal representation of docker containers // Container represents an internal representation of docker containers
@@ -41,6 +43,34 @@ type ContainerEvent struct {
ActorAttributes map[string]string `json:"actorAttributes,omitempty"` ActorAttributes map[string]string `json:"actorAttributes,omitempty"`
} }
type ContainerFilter map[string][]string
func NewContainerFilter(values map[string]string) (ContainerFilter, error) {
containerFilter := make(ContainerFilter)
for _, filter := range values {
pos := strings.Index(filter, "=")
if pos == -1 {
return nil, fmt.Errorf("invalid filter: %s. each filter should be of the form key=value", filter)
}
key := filter[:pos]
val := filter[pos+1:]
containerFilter[key] = append(containerFilter[key], val)
}
return containerFilter, nil
}
func (f ContainerFilter) asArgs() filters.Args {
filterArgs := filters.NewArgs()
for key, values := range f {
for _, value := range values {
filterArgs.Add(key, value)
}
}
return filterArgs
}
type LogPosition string type LogPosition string
const ( const (

View File

@@ -5,6 +5,7 @@ import (
"crypto/tls" "crypto/tls"
"github.com/amir20/dozzle/internal/agent" "github.com/amir20/dozzle/internal/agent"
"github.com/amir20/dozzle/internal/docker"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
@@ -13,7 +14,7 @@ func RPCRequest(ctx context.Context, addr string, certs tls.Certificate) error {
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Failed to create agent client") log.Fatal().Err(err).Msg("Failed to create agent client")
} }
containers, err := client.ListContainers(ctx) containers, err := client.ListContainers(ctx, docker.ContainerFilter{})
log.Trace().Int("containers", len(containers)).Msg("Healtcheck RPC request completed") log.Trace().Int("containers", len(containers)).Msg("Healtcheck RPC request completed")
return err return err
} }

View File

@@ -22,11 +22,11 @@ func CreateMultiHostService(embeddedCerts embed.FS, args Args) (docker.Client, *
} }
log.Info().Interface("host", host).Msg("Adding remote host") log.Info().Interface("host", host).Msg("Adding remote host")
if client, err := docker.NewRemoteClient(args.Filter, host); err == nil { if client, err := docker.NewRemoteClient(host); err == nil {
ctx, cancel := context.WithTimeout(context.Background(), args.Timeout) ctx, cancel := context.WithTimeout(context.Background(), args.Timeout)
defer cancel() defer cancel()
if _, err := client.ListContainers(ctx); err == nil { if _, err := client.ListContainers(ctx, args.Filter); err == nil {
clients = append(clients, docker_support.NewDockerClientService(client)) clients = append(clients, docker_support.NewDockerClientService(client, args.Filter))
} else { } else {
log.Warn().Err(err).Interface("host", host).Msg("Could not connect to remote host") log.Warn().Err(err).Interface("host", host).Msg("Could not connect to remote host")
} }
@@ -35,16 +35,16 @@ func CreateMultiHostService(embeddedCerts embed.FS, args Args) (docker.Client, *
} }
} }
localClient, err := docker.NewLocalClient(args.Filter, args.Hostname) localClient, err := docker.NewLocalClient(args.Hostname)
if err == nil { if err == nil {
ctx, cancel := context.WithTimeout(context.Background(), args.Timeout) ctx, cancel := context.WithTimeout(context.Background(), args.Timeout)
defer cancel() defer cancel()
_, err := localClient.ListContainers(ctx) _, err := localClient.ListContainers(ctx, args.Filter)
if err != nil { if err != nil {
log.Debug().Err(err).Msg("Could not connect to local Docker Engine") log.Debug().Err(err).Msg("Could not connect to local Docker Engine")
} else { } else {
log.Debug().Msg("Adding local Docker Engine") log.Debug().Msg("Adding local Docker Engine")
clients = append(clients, docker_support.NewDockerClientService(localClient)) clients = append(clients, docker_support.NewDockerClientService(localClient, args.Filter))
} }
} }

View File

@@ -36,8 +36,8 @@ func (a *agentService) StreamLogs(ctx context.Context, container docker.Containe
return a.client.StreamContainerLogs(ctx, container.ID, from, stdTypes, events) return a.client.StreamContainerLogs(ctx, container.ID, from, stdTypes, events)
} }
func (a *agentService) ListContainers(ctx context.Context) ([]docker.Container, error) { func (a *agentService) ListContainers(ctx context.Context, filter docker.ContainerFilter) ([]docker.Container, error) {
return a.client.ListContainers(ctx) return a.client.ListContainers(ctx, filter)
} }
func (a *agentService) Host(ctx context.Context) (docker.Host, error) { func (a *agentService) Host(ctx context.Context) (docker.Host, error) {

View File

@@ -10,7 +10,7 @@ import (
type ClientService interface { type ClientService interface {
FindContainer(ctx context.Context, id string) (docker.Container, error) FindContainer(ctx context.Context, id string) (docker.Container, error)
ListContainers(ctx context.Context) ([]docker.Container, error) ListContainers(ctx context.Context, filter docker.ContainerFilter) ([]docker.Container, error)
Host(ctx context.Context) (docker.Host, error) Host(ctx context.Context) (docker.Host, error)
ContainerAction(ctx context.Context, container docker.Container, action docker.ContainerAction) error ContainerAction(ctx context.Context, container docker.Container, action docker.ContainerAction) error
LogsBetweenDates(ctx context.Context, container docker.Container, from time.Time, to time.Time, stdTypes docker.StdType) (<-chan *docker.LogEvent, error) LogsBetweenDates(ctx context.Context, container docker.Container, from time.Time, to time.Time, stdTypes docker.StdType) (<-chan *docker.LogEvent, error)
@@ -30,10 +30,10 @@ type dockerClientService struct {
store *docker.ContainerStore store *docker.ContainerStore
} }
func NewDockerClientService(client docker.Client) ClientService { func NewDockerClientService(client docker.Client, filter docker.ContainerFilter) ClientService {
return &dockerClientService{ return &dockerClientService{
client: client, client: client,
store: docker.NewContainerStore(context.Background(), client), store: docker.NewContainerStore(context.Background(), client, filter),
} }
} }
@@ -78,8 +78,8 @@ func (d *dockerClientService) ContainerAction(ctx context.Context, container doc
return d.client.ContainerActions(ctx, action, container.ID) return d.client.ContainerActions(ctx, action, container.ID)
} }
func (d *dockerClientService) ListContainers(ctx context.Context) ([]docker.Container, error) { func (d *dockerClientService) ListContainers(ctx context.Context, filter docker.ContainerFilter) ([]docker.Container, error) {
return d.store.ListContainers() return d.store.ListContainers(filter)
} }
func (d *dockerClientService) Host(ctx context.Context) (docker.Host, error) { func (d *dockerClientService) Host(ctx context.Context) (docker.Host, error) {

View File

@@ -61,7 +61,7 @@ func (m *MultiHostService) FindContainer(host string, id string) (*containerServ
}, nil }, nil
} }
func (m *MultiHostService) ListContainersForHost(host string) ([]docker.Container, error) { func (m *MultiHostService) ListContainersForHost(host string, filter docker.ContainerFilter) ([]docker.Container, error) {
client, ok := m.manager.Find(host) client, ok := m.manager.Find(host)
if !ok { if !ok {
return nil, fmt.Errorf("host %s not found", host) return nil, fmt.Errorf("host %s not found", host)
@@ -69,17 +69,17 @@ func (m *MultiHostService) ListContainersForHost(host string) ([]docker.Containe
ctx, cancel := context.WithTimeout(context.Background(), m.timeout) ctx, cancel := context.WithTimeout(context.Background(), m.timeout)
defer cancel() defer cancel()
return client.ListContainers(ctx) return client.ListContainers(ctx, filter)
} }
func (m *MultiHostService) ListAllContainers() ([]docker.Container, []error) { func (m *MultiHostService) ListAllContainers(filter docker.ContainerFilter) ([]docker.Container, []error) {
containers := make([]docker.Container, 0) containers := make([]docker.Container, 0)
clients, errors := m.manager.RetryAndList() clients, errors := m.manager.RetryAndList()
for _, client := range clients { for _, client := range clients {
ctx, cancel := context.WithTimeout(context.Background(), m.timeout) ctx, cancel := context.WithTimeout(context.Background(), m.timeout)
defer cancel() defer cancel()
list, err := client.ListContainers(ctx) list, err := client.ListContainers(ctx, filter)
if err != nil { if err != nil {
host, _ := client.Host(ctx) host, _ := client.Host(ctx)
log.Debug().Err(err).Str("host", host.Name).Msg("error listing containers") log.Debug().Err(err).Str("host", host.Name).Msg("error listing containers")
@@ -94,8 +94,8 @@ func (m *MultiHostService) ListAllContainers() ([]docker.Container, []error) {
return containers, errors return containers, errors
} }
func (m *MultiHostService) ListAllContainersFiltered(filter ContainerFilter) ([]docker.Container, []error) { func (m *MultiHostService) ListAllContainersFiltered(userFilter docker.ContainerFilter, filter ContainerFilter) ([]docker.Container, []error) {
containers, err := m.ListAllContainers() containers, err := m.ListAllContainers(userFilter)
filtered := make([]docker.Container, 0, len(containers)) filtered := make([]docker.Container, 0, len(containers))
for _, container := range containers { for _, container := range containers {
if filter(&container) { if filter(&container) {

View File

@@ -47,9 +47,9 @@ func localIPs() []string {
return ips return ips
} }
func NewSwarmClientManager(localClient docker.Client, certs tls.Certificate, timeout time.Duration, agentManager *RetriableClientManager) *SwarmClientManager { func NewSwarmClientManager(localClient docker.Client, certs tls.Certificate, timeout time.Duration, agentManager *RetriableClientManager, filter docker.ContainerFilter) *SwarmClientManager {
clientMap := make(map[string]ClientService) clientMap := make(map[string]ClientService)
localService := NewDockerClientService(localClient) localService := NewDockerClientService(localClient, filter)
clientMap[localClient.Host().ID] = localService clientMap[localClient.Host().ID] = localService
id, ok := os.LookupEnv("HOSTNAME") id, ok := os.LookupEnv("HOSTNAME")

View File

@@ -3,12 +3,14 @@ package web
import ( import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"github.com/amir20/dozzle/internal/docker"
) )
func (h *handler) debugStore(w http.ResponseWriter, r *http.Request) { func (h *handler) debugStore(w http.ResponseWriter, r *http.Request) {
respone := make(map[string]interface{}) respone := make(map[string]interface{})
respone["hosts"] = h.multiHostService.Hosts() respone["hosts"] = h.multiHostService.Hosts()
containers, errors := h.multiHostService.ListAllContainers() containers, errors := h.multiHostService.ListAllContainers(docker.ContainerFilter{})
respone["containers"] = containers respone["containers"] = containers
respone["errors"] = errors respone["errors"] = errors

View File

@@ -25,7 +25,8 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
h.multiHostService.SubscribeEventsAndStats(r.Context(), events, stats) h.multiHostService.SubscribeEventsAndStats(r.Context(), events, stats)
h.multiHostService.SubscribeAvailableHosts(r.Context(), availableHosts) h.multiHostService.SubscribeAvailableHosts(r.Context(), availableHosts)
allContainers, errors := h.multiHostService.ListAllContainers() // TODO - No user data so just fetch all containers
allContainers, errors := h.multiHostService.ListAllContainers(docker.ContainerFilter{})
for _, err := range errors { for _, err := range errors {
log.Warn().Err(err).Msg("error listing containers") log.Warn().Err(err).Msg("error listing containers")
@@ -63,7 +64,7 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
if event.Name == "start" || event.Name == "rename" { if event.Name == "start" || event.Name == "rename" {
log.Debug().Str("action", event.Name).Str("id", event.ActorID).Msg("container event") log.Debug().Str("action", event.Name).Str("id", event.ActorID).Msg("container event")
if containers, err := h.multiHostService.ListContainersForHost(event.Host); err == nil { if containers, err := h.multiHostService.ListContainersForHost(event.Host, docker.ContainerFilter{}); err == nil {
if err := sseWriter.Event("containers-changed", containers); err != nil { if err := sseWriter.Event("containers-changed", containers); err != nil {
log.Error().Err(err).Msg("error writing containers to event stream") log.Error().Err(err).Msg("error writing containers to event stream")
return return

View File

@@ -288,7 +288,7 @@ func streamLogsForContainers(w http.ResponseWriter, r *http.Request, multiHostCl
return return
} }
existingContainers, errs := multiHostClient.ListAllContainersFiltered(filter) existingContainers, errs := multiHostClient.ListAllContainersFiltered(docker.ContainerFilter{}, filter)
if len(errs) > 0 { if len(errs) > 0 {
log.Warn().Err(errs[0]).Msg("error while listing containers") log.Warn().Err(errs[0]).Msg("error while listing containers")
} }

10
main.go
View File

@@ -37,7 +37,7 @@ func main() {
if subcommand != nil { if subcommand != nil {
switch subcommand.(type) { switch subcommand.(type) {
case *cli.AgentCmd: case *cli.AgentCmd:
client, err := docker.NewLocalClient(args.Filter, args.Hostname) client, err := docker.NewLocalClient(args.Hostname)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Could not create docker client") log.Fatal().Err(err).Msg("Could not create docker client")
} }
@@ -56,7 +56,7 @@ func main() {
} }
io.WriteString(tempFile, listener.Addr().String()) io.WriteString(tempFile, listener.Addr().String())
go cli.StartEvent(args, "", client, "agent") go cli.StartEvent(args, "", client, "agent")
server, err := agent.NewServer(client, certs, args.Version()) server, err := agent.NewServer(client, certs, args.Version(), args.Filter)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("failed to create agent server") log.Fatal().Err(err).Msg("failed to create agent server")
} }
@@ -170,7 +170,7 @@ func main() {
go cli.StartEvent(args, "server", localClient, "") go cli.StartEvent(args, "server", localClient, "")
} else if args.Mode == "swarm" { } else if args.Mode == "swarm" {
localClient, err := docker.NewLocalClient(args.Filter, args.Hostname) localClient, err := docker.NewLocalClient(args.Hostname)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Could not create docker client") log.Fatal().Err(err).Msg("Could not create docker client")
} }
@@ -179,14 +179,14 @@ func main() {
log.Fatal().Err(err).Msg("Could not read certificates") log.Fatal().Err(err).Msg("Could not read certificates")
} }
agentManager := docker_support.NewRetriableClientManager(args.RemoteAgent, args.Timeout, certs) agentManager := docker_support.NewRetriableClientManager(args.RemoteAgent, args.Timeout, certs)
manager := docker_support.NewSwarmClientManager(localClient, certs, args.Timeout, agentManager) manager := docker_support.NewSwarmClientManager(localClient, certs, args.Timeout, agentManager, args.Filter)
multiHostService = docker_support.NewMultiHostService(manager, args.Timeout) multiHostService = docker_support.NewMultiHostService(manager, args.Timeout)
log.Info().Msg("Starting in swarm mode") log.Info().Msg("Starting in swarm mode")
listener, err := net.Listen("tcp", ":7007") listener, err := net.Listen("tcp", ":7007")
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("failed to listen") log.Fatal().Err(err).Msg("failed to listen")
} }
server, err := agent.NewServer(localClient, certs, args.Version()) server, err := agent.NewServer(localClient, certs, args.Version(), args.Filter)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("failed to create agent") log.Fatal().Err(err).Msg("failed to create agent")
} }

View File

@@ -23,7 +23,9 @@ service AgentService {
returns (ContainerActionResponse) {} returns (ContainerActionResponse) {}
} }
message ListContainersRequest {} message ListContainersRequest { map<string, RepeatedString> filter = 1; }
message RepeatedString { repeated string values = 1; }
message ListContainersResponse { repeated Container containers = 1; } message ListContainersResponse { repeated Container containers = 1; }
@@ -72,5 +74,4 @@ message ContainerActionRequest {
ContainerAction action = 2; ContainerAction action = 2;
} }
message ContainerActionResponse { message ContainerActionResponse {}
}