diff --git a/hack/update-codegen-dockerized.sh b/hack/update-codegen-dockerized.sh index 091693f3ca7..6c4fa2d6fd4 100755 --- a/hack/update-codegen-dockerized.sh +++ b/hack/update-codegen-dockerized.sh @@ -102,6 +102,7 @@ function generate_antrea_client_code { --plural-exceptions "AntreaNetworkPolicyStats:AntreaNetworkPolicyStats" \ --plural-exceptions "AntreaClusterNetworkPolicyStats:AntreaClusterNetworkPolicyStats" \ --plural-exceptions "ClusterGroupMembers:ClusterGroupMembers" \ + --plural-exceptions "GroupMembers:GroupMembers" \ --go-header-file hack/boilerplate/license_header.go.txt # Generate listers with K8s codegen tools. diff --git a/pkg/apis/controlplane/register.go b/pkg/apis/controlplane/register.go index 6e79ee22d18..42a27ddeab8 100644 --- a/pkg/apis/controlplane/register.go +++ b/pkg/apis/controlplane/register.go @@ -56,6 +56,7 @@ func addKnownTypes(scheme *runtime.Scheme) error { &NetworkPolicyStatus{}, &NodeStatsSummary{}, &ClusterGroupMembers{}, + &GroupMembers{}, &PaginationGetOptions{}, &GroupAssociation{}, &IPGroupAssociation{}, diff --git a/pkg/apis/controlplane/types.go b/pkg/apis/controlplane/types.go index 2e81bdd1381..6f576d4f9e1 100644 --- a/pkg/apis/controlplane/types.go +++ b/pkg/apis/controlplane/types.go @@ -95,7 +95,7 @@ type GroupMember struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// ClusterGroupMembers is a list of GroupMember objects or ipBlocks that are currently selected by a ClusterGroup. +// ClusterGroupMembers is a list of GroupMember objects or IPBlocks that are currently selected by a ClusterGroup. type ClusterGroupMembers struct { metav1.TypeMeta metav1.ObjectMeta @@ -106,6 +106,19 @@ type ClusterGroupMembers struct { CurrentPage int64 } +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GroupMembers is a list of GroupMember objects or IPBlocks that are currently selected by a Group. +type GroupMembers struct { + metav1.TypeMeta + metav1.ObjectMeta + EffectiveMembers []GroupMember + EffectiveIPBlocks []IPNet + TotalMembers int64 + TotalPages int64 + CurrentPage int64 +} + // +k8s:conversion-gen:explicit-from=net/url.Values // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/controlplane/v1beta2/generated.pb.go b/pkg/apis/controlplane/v1beta2/generated.pb.go index 5f0ea38ce5a..3247f1e1ff7 100644 --- a/pkg/apis/controlplane/v1beta2/generated.pb.go +++ b/pkg/apis/controlplane/v1beta2/generated.pb.go @@ -495,10 +495,38 @@ func (m *GroupMember) XXX_DiscardUnknown() { var xxx_messageInfo_GroupMember proto.InternalMessageInfo +func (m *GroupMembers) Reset() { *m = GroupMembers{} } +func (*GroupMembers) ProtoMessage() {} +func (*GroupMembers) Descriptor() ([]byte, []int) { + return fileDescriptor_fbaa7d016762fa1d, []int{16} +} +func (m *GroupMembers) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GroupMembers) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *GroupMembers) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupMembers.Merge(m, src) +} +func (m *GroupMembers) XXX_Size() int { + return m.Size() +} +func (m *GroupMembers) XXX_DiscardUnknown() { + xxx_messageInfo_GroupMembers.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupMembers proto.InternalMessageInfo + func (m *GroupReference) Reset() { *m = GroupReference{} } func (*GroupReference) ProtoMessage() {} func (*GroupReference) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{16} + return fileDescriptor_fbaa7d016762fa1d, []int{17} } func (m *GroupReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -526,7 +554,7 @@ var xxx_messageInfo_GroupReference proto.InternalMessageInfo func (m *HTTPProtocol) Reset() { *m = HTTPProtocol{} } func (*HTTPProtocol) ProtoMessage() {} func (*HTTPProtocol) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{17} + return fileDescriptor_fbaa7d016762fa1d, []int{18} } func (m *HTTPProtocol) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -554,7 +582,7 @@ var xxx_messageInfo_HTTPProtocol proto.InternalMessageInfo func (m *IPBlock) Reset() { *m = IPBlock{} } func (*IPBlock) ProtoMessage() {} func (*IPBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{18} + return fileDescriptor_fbaa7d016762fa1d, []int{19} } func (m *IPBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -582,7 +610,7 @@ var xxx_messageInfo_IPBlock proto.InternalMessageInfo func (m *IPGroupAssociation) Reset() { *m = IPGroupAssociation{} } func (*IPGroupAssociation) ProtoMessage() {} func (*IPGroupAssociation) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{19} + return fileDescriptor_fbaa7d016762fa1d, []int{20} } func (m *IPGroupAssociation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -610,7 +638,7 @@ var xxx_messageInfo_IPGroupAssociation proto.InternalMessageInfo func (m *IPNet) Reset() { *m = IPNet{} } func (*IPNet) ProtoMessage() {} func (*IPNet) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{20} + return fileDescriptor_fbaa7d016762fa1d, []int{21} } func (m *IPNet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -638,7 +666,7 @@ var xxx_messageInfo_IPNet proto.InternalMessageInfo func (m *L7Protocol) Reset() { *m = L7Protocol{} } func (*L7Protocol) ProtoMessage() {} func (*L7Protocol) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{21} + return fileDescriptor_fbaa7d016762fa1d, []int{22} } func (m *L7Protocol) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -666,7 +694,7 @@ var xxx_messageInfo_L7Protocol proto.InternalMessageInfo func (m *MulticastGroupInfo) Reset() { *m = MulticastGroupInfo{} } func (*MulticastGroupInfo) ProtoMessage() {} func (*MulticastGroupInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{22} + return fileDescriptor_fbaa7d016762fa1d, []int{23} } func (m *MulticastGroupInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -694,7 +722,7 @@ var xxx_messageInfo_MulticastGroupInfo proto.InternalMessageInfo func (m *NamedPort) Reset() { *m = NamedPort{} } func (*NamedPort) ProtoMessage() {} func (*NamedPort) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{23} + return fileDescriptor_fbaa7d016762fa1d, []int{24} } func (m *NamedPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -722,7 +750,7 @@ var xxx_messageInfo_NamedPort proto.InternalMessageInfo func (m *NetworkPolicy) Reset() { *m = NetworkPolicy{} } func (*NetworkPolicy) ProtoMessage() {} func (*NetworkPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{24} + return fileDescriptor_fbaa7d016762fa1d, []int{25} } func (m *NetworkPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -750,7 +778,7 @@ var xxx_messageInfo_NetworkPolicy proto.InternalMessageInfo func (m *NetworkPolicyList) Reset() { *m = NetworkPolicyList{} } func (*NetworkPolicyList) ProtoMessage() {} func (*NetworkPolicyList) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{25} + return fileDescriptor_fbaa7d016762fa1d, []int{26} } func (m *NetworkPolicyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -778,7 +806,7 @@ var xxx_messageInfo_NetworkPolicyList proto.InternalMessageInfo func (m *NetworkPolicyNodeStatus) Reset() { *m = NetworkPolicyNodeStatus{} } func (*NetworkPolicyNodeStatus) ProtoMessage() {} func (*NetworkPolicyNodeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{26} + return fileDescriptor_fbaa7d016762fa1d, []int{27} } func (m *NetworkPolicyNodeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -806,7 +834,7 @@ var xxx_messageInfo_NetworkPolicyNodeStatus proto.InternalMessageInfo func (m *NetworkPolicyPeer) Reset() { *m = NetworkPolicyPeer{} } func (*NetworkPolicyPeer) ProtoMessage() {} func (*NetworkPolicyPeer) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{27} + return fileDescriptor_fbaa7d016762fa1d, []int{28} } func (m *NetworkPolicyPeer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -834,7 +862,7 @@ var xxx_messageInfo_NetworkPolicyPeer proto.InternalMessageInfo func (m *NetworkPolicyReference) Reset() { *m = NetworkPolicyReference{} } func (*NetworkPolicyReference) ProtoMessage() {} func (*NetworkPolicyReference) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{28} + return fileDescriptor_fbaa7d016762fa1d, []int{29} } func (m *NetworkPolicyReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -862,7 +890,7 @@ var xxx_messageInfo_NetworkPolicyReference proto.InternalMessageInfo func (m *NetworkPolicyRule) Reset() { *m = NetworkPolicyRule{} } func (*NetworkPolicyRule) ProtoMessage() {} func (*NetworkPolicyRule) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{29} + return fileDescriptor_fbaa7d016762fa1d, []int{30} } func (m *NetworkPolicyRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -890,7 +918,7 @@ var xxx_messageInfo_NetworkPolicyRule proto.InternalMessageInfo func (m *NetworkPolicyStats) Reset() { *m = NetworkPolicyStats{} } func (*NetworkPolicyStats) ProtoMessage() {} func (*NetworkPolicyStats) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{30} + return fileDescriptor_fbaa7d016762fa1d, []int{31} } func (m *NetworkPolicyStats) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -918,7 +946,7 @@ var xxx_messageInfo_NetworkPolicyStats proto.InternalMessageInfo func (m *NetworkPolicyStatus) Reset() { *m = NetworkPolicyStatus{} } func (*NetworkPolicyStatus) ProtoMessage() {} func (*NetworkPolicyStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{31} + return fileDescriptor_fbaa7d016762fa1d, []int{32} } func (m *NetworkPolicyStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -946,7 +974,7 @@ var xxx_messageInfo_NetworkPolicyStatus proto.InternalMessageInfo func (m *NodeReference) Reset() { *m = NodeReference{} } func (*NodeReference) ProtoMessage() {} func (*NodeReference) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{32} + return fileDescriptor_fbaa7d016762fa1d, []int{33} } func (m *NodeReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -974,7 +1002,7 @@ var xxx_messageInfo_NodeReference proto.InternalMessageInfo func (m *NodeStatsSummary) Reset() { *m = NodeStatsSummary{} } func (*NodeStatsSummary) ProtoMessage() {} func (*NodeStatsSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{33} + return fileDescriptor_fbaa7d016762fa1d, []int{34} } func (m *NodeStatsSummary) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1002,7 +1030,7 @@ var xxx_messageInfo_NodeStatsSummary proto.InternalMessageInfo func (m *PaginationGetOptions) Reset() { *m = PaginationGetOptions{} } func (*PaginationGetOptions) ProtoMessage() {} func (*PaginationGetOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{34} + return fileDescriptor_fbaa7d016762fa1d, []int{35} } func (m *PaginationGetOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1030,7 +1058,7 @@ var xxx_messageInfo_PaginationGetOptions proto.InternalMessageInfo func (m *PodReference) Reset() { *m = PodReference{} } func (*PodReference) ProtoMessage() {} func (*PodReference) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{35} + return fileDescriptor_fbaa7d016762fa1d, []int{36} } func (m *PodReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1058,7 +1086,7 @@ var xxx_messageInfo_PodReference proto.InternalMessageInfo func (m *Service) Reset() { *m = Service{} } func (*Service) ProtoMessage() {} func (*Service) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{36} + return fileDescriptor_fbaa7d016762fa1d, []int{37} } func (m *Service) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1086,7 +1114,7 @@ var xxx_messageInfo_Service proto.InternalMessageInfo func (m *ServiceReference) Reset() { *m = ServiceReference{} } func (*ServiceReference) ProtoMessage() {} func (*ServiceReference) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{37} + return fileDescriptor_fbaa7d016762fa1d, []int{38} } func (m *ServiceReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1114,7 +1142,7 @@ var xxx_messageInfo_ServiceReference proto.InternalMessageInfo func (m *SupportBundleCollection) Reset() { *m = SupportBundleCollection{} } func (*SupportBundleCollection) ProtoMessage() {} func (*SupportBundleCollection) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{38} + return fileDescriptor_fbaa7d016762fa1d, []int{39} } func (m *SupportBundleCollection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1142,7 +1170,7 @@ var xxx_messageInfo_SupportBundleCollection proto.InternalMessageInfo func (m *SupportBundleCollectionList) Reset() { *m = SupportBundleCollectionList{} } func (*SupportBundleCollectionList) ProtoMessage() {} func (*SupportBundleCollectionList) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{39} + return fileDescriptor_fbaa7d016762fa1d, []int{40} } func (m *SupportBundleCollectionList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1170,7 +1198,7 @@ var xxx_messageInfo_SupportBundleCollectionList proto.InternalMessageInfo func (m *SupportBundleCollectionNodeStatus) Reset() { *m = SupportBundleCollectionNodeStatus{} } func (*SupportBundleCollectionNodeStatus) ProtoMessage() {} func (*SupportBundleCollectionNodeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{40} + return fileDescriptor_fbaa7d016762fa1d, []int{41} } func (m *SupportBundleCollectionNodeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1198,7 +1226,7 @@ var xxx_messageInfo_SupportBundleCollectionNodeStatus proto.InternalMessageInfo func (m *SupportBundleCollectionStatus) Reset() { *m = SupportBundleCollectionStatus{} } func (*SupportBundleCollectionStatus) ProtoMessage() {} func (*SupportBundleCollectionStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{41} + return fileDescriptor_fbaa7d016762fa1d, []int{42} } func (m *SupportBundleCollectionStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1226,7 +1254,7 @@ var xxx_messageInfo_SupportBundleCollectionStatus proto.InternalMessageInfo func (m *TLSProtocol) Reset() { *m = TLSProtocol{} } func (*TLSProtocol) ProtoMessage() {} func (*TLSProtocol) Descriptor() ([]byte, []int) { - return fileDescriptor_fbaa7d016762fa1d, []int{42} + return fileDescriptor_fbaa7d016762fa1d, []int{43} } func (m *TLSProtocol) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1268,6 +1296,7 @@ func init() { proto.RegisterType((*ExternalEntityReference)(nil), "antrea_io.antrea.pkg.apis.controlplane.v1beta2.ExternalEntityReference") proto.RegisterType((*GroupAssociation)(nil), "antrea_io.antrea.pkg.apis.controlplane.v1beta2.GroupAssociation") proto.RegisterType((*GroupMember)(nil), "antrea_io.antrea.pkg.apis.controlplane.v1beta2.GroupMember") + proto.RegisterType((*GroupMembers)(nil), "antrea_io.antrea.pkg.apis.controlplane.v1beta2.GroupMembers") proto.RegisterType((*GroupReference)(nil), "antrea_io.antrea.pkg.apis.controlplane.v1beta2.GroupReference") proto.RegisterType((*HTTPProtocol)(nil), "antrea_io.antrea.pkg.apis.controlplane.v1beta2.HTTPProtocol") proto.RegisterType((*IPBlock)(nil), "antrea_io.antrea.pkg.apis.controlplane.v1beta2.IPBlock") @@ -1302,186 +1331,186 @@ func init() { } var fileDescriptor_fbaa7d016762fa1d = []byte{ - // 2852 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3a, 0xcd, 0x6f, 0x24, 0xc5, - 0xf5, 0xdb, 0x9e, 0x19, 0xdb, 0xf3, 0xc6, 0xf6, 0x7a, 0xcb, 0xc0, 0xfa, 0x07, 0xac, 0xbd, 0x34, - 0xbf, 0xa0, 0x4d, 0x44, 0x66, 0xb0, 0x03, 0xec, 0x86, 0x2f, 0xc5, 0xe3, 0xf5, 0x9a, 0x09, 0xb6, - 0x19, 0x6a, 0x06, 0x90, 0x20, 0x10, 0xda, 0xdd, 0x35, 0xe3, 0x8e, 0x7b, 0xba, 0x9a, 0xea, 0x1a, - 0xb3, 0xe6, 0x10, 0x11, 0x91, 0x1c, 0xc8, 0x17, 0x51, 0x2e, 0x51, 0x6e, 0xb9, 0xe5, 0x92, 0xbf, - 0x80, 0x53, 0x38, 0x44, 0xe2, 0x48, 0x14, 0x45, 0xe1, 0x64, 0x65, 0x1d, 0x85, 0x88, 0x43, 0x2e, - 0xb9, 0x65, 0xa3, 0x48, 0x51, 0x55, 0x57, 0x77, 0x57, 0xcf, 0x78, 0xd6, 0x3b, 0xb6, 0xd7, 0x91, - 0x02, 0xa7, 0x99, 0x7e, 0xdf, 0x55, 0xf5, 0x5e, 0xbd, 0x8f, 0x6e, 0x78, 0xc6, 0xf2, 0x39, 0x23, - 0x56, 0xd9, 0xa5, 0x95, 0xe8, 0x5f, 0x25, 0xd8, 0x6e, 0x57, 0xac, 0xc0, 0x0d, 0x2b, 0x36, 0xf5, - 0x39, 0xa3, 0x5e, 0xe0, 0x59, 0x3e, 0xa9, 0xec, 0x2c, 0x6c, 0x12, 0x6e, 0x2d, 0x56, 0xda, 0xc4, - 0x27, 0xcc, 0xe2, 0xc4, 0x29, 0x07, 0x8c, 0x72, 0x8a, 0xca, 0x11, 0xd7, 0xb7, 0x5d, 0xaa, 0xfe, - 0x95, 0x83, 0xed, 0x76, 0x59, 0xf0, 0x97, 0x75, 0xfe, 0xb2, 0xe2, 0xbf, 0xf7, 0xca, 0x60, 0x7d, - 0x21, 0xb7, 0x78, 0x58, 0xd9, 0x59, 0xb0, 0xbc, 0x60, 0xcb, 0x5a, 0xe8, 0xd5, 0x74, 0xef, 0x57, - 0xdb, 0x2e, 0xdf, 0xea, 0x6e, 0x96, 0x6d, 0xda, 0xa9, 0xb4, 0x69, 0x9b, 0x56, 0x24, 0x78, 0xb3, - 0xdb, 0x92, 0x4f, 0xf2, 0x41, 0xfe, 0x53, 0xe4, 0x8f, 0x6e, 0x5f, 0x09, 0xa5, 0x96, 0xc0, 0xed, - 0x58, 0xf6, 0x96, 0xeb, 0x13, 0xb6, 0x9b, 0xea, 0xea, 0x10, 0x6e, 0x55, 0x76, 0xfa, 0x95, 0x54, - 0x06, 0x71, 0xb1, 0xae, 0xcf, 0xdd, 0x0e, 0xe9, 0x63, 0x78, 0xfc, 0x30, 0x86, 0xd0, 0xde, 0x22, - 0x1d, 0xab, 0x8f, 0xef, 0x6b, 0x83, 0xf8, 0xba, 0xdc, 0xf5, 0x2a, 0xae, 0xcf, 0x43, 0xce, 0x7a, - 0x99, 0xcc, 0xbf, 0x19, 0x30, 0xb1, 0xe4, 0x38, 0x8c, 0x84, 0xe1, 0x2a, 0xa3, 0xdd, 0x00, 0xbd, - 0x01, 0xe3, 0x62, 0x25, 0x8e, 0xc5, 0xad, 0x59, 0xe3, 0xa2, 0x71, 0xa9, 0xb4, 0xf8, 0x48, 0x39, - 0x12, 0x5c, 0xd6, 0x05, 0xa7, 0x67, 0x22, 0xa8, 0xcb, 0x3b, 0x0b, 0xe5, 0xe7, 0x37, 0xbf, 0x43, - 0x6c, 0xbe, 0x4e, 0xb8, 0x55, 0x45, 0x1f, 0xed, 0xcd, 0x9f, 0xd9, 0xdf, 0x9b, 0x87, 0x14, 0x86, - 0x13, 0xa9, 0xa8, 0x0b, 0x13, 0x6d, 0xa1, 0x6a, 0x9d, 0x74, 0x36, 0x09, 0x0b, 0x67, 0x47, 0x2e, - 0xe6, 0x2e, 0x95, 0x16, 0x9f, 0x1c, 0xf2, 0xd8, 0xcb, 0xab, 0xa9, 0x8c, 0xea, 0x5d, 0x4a, 0xe1, - 0x84, 0x06, 0x0c, 0x71, 0x46, 0x8d, 0xf9, 0x07, 0x03, 0xa6, 0xf5, 0x95, 0xae, 0xb9, 0x21, 0x47, - 0xdf, 0xea, 0x5b, 0x6d, 0xf9, 0xf6, 0x56, 0x2b, 0xb8, 0xe5, 0x5a, 0xa7, 0x95, 0xea, 0xf1, 0x18, - 0xa2, 0xad, 0xd4, 0x82, 0x82, 0xcb, 0x49, 0x27, 0x5e, 0xe2, 0x53, 0xc3, 0x2e, 0x51, 0x37, 0xb7, - 0x3a, 0xa9, 0x14, 0x15, 0x6a, 0x42, 0x24, 0x8e, 0x24, 0x9b, 0xef, 0xe5, 0xe0, 0x9c, 0x4e, 0x56, - 0xb7, 0xb8, 0xbd, 0x75, 0x0a, 0x87, 0xf8, 0x7d, 0x03, 0xce, 0x59, 0x8e, 0x43, 0x9c, 0xd5, 0x13, - 0x3e, 0xca, 0xff, 0x53, 0x6a, 0xc5, 0xaa, 0xb2, 0xd2, 0x71, 0xbf, 0x42, 0xf4, 0x43, 0x03, 0x66, - 0x18, 0xe9, 0xd0, 0x9d, 0x1e, 0x43, 0x72, 0xc7, 0x37, 0xe4, 0x3e, 0x65, 0xc8, 0x0c, 0xee, 0x97, - 0x8f, 0x0f, 0x52, 0x6a, 0x7e, 0x66, 0xc0, 0xd4, 0x52, 0x10, 0x78, 0x2e, 0x71, 0x9a, 0xf4, 0x7f, - 0x3c, 0x9a, 0xfe, 0x64, 0x00, 0xca, 0xae, 0xf5, 0x14, 0xe2, 0xc9, 0xce, 0xc6, 0xd3, 0x33, 0x43, - 0xc7, 0x53, 0xc6, 0xe0, 0x01, 0x11, 0xf5, 0xa3, 0x1c, 0xcc, 0x64, 0x09, 0xbf, 0x88, 0xa9, 0xff, - 0x5e, 0x4c, 0xbd, 0x09, 0x33, 0x55, 0x2b, 0x74, 0xed, 0xa5, 0x2e, 0xdf, 0x22, 0x3e, 0x77, 0x6d, - 0x8b, 0xbb, 0xd4, 0x47, 0x0f, 0xc3, 0x78, 0x37, 0x24, 0xcc, 0xb7, 0x3a, 0x44, 0x1e, 0x46, 0x31, - 0xf5, 0x9b, 0x17, 0x15, 0x1c, 0x27, 0x14, 0x82, 0x3a, 0xb0, 0xc2, 0xf0, 0x2d, 0xca, 0x9c, 0xd9, - 0x91, 0x2c, 0x75, 0x5d, 0xc1, 0x71, 0x42, 0x61, 0x2e, 0xc0, 0x74, 0xb5, 0xeb, 0x3b, 0x1e, 0xb9, - 0xe6, 0x7a, 0xa4, 0x41, 0xd8, 0x0e, 0x61, 0xe8, 0x02, 0xe4, 0xba, 0xcc, 0x53, 0xaa, 0x4a, 0x8a, - 0x39, 0xf7, 0x22, 0x5e, 0xc3, 0x02, 0x6e, 0xbe, 0x3f, 0x02, 0x17, 0x22, 0x9e, 0x88, 0x5e, 0x58, - 0xbb, 0x4c, 0xfd, 0x96, 0xdb, 0xee, 0xb2, 0xc8, 0xe0, 0xc7, 0xa0, 0xb4, 0x49, 0x2c, 0x46, 0x58, - 0x93, 0x6e, 0x13, 0x5f, 0x09, 0x9a, 0x51, 0x82, 0x4a, 0xd5, 0x14, 0x85, 0x75, 0x3a, 0xf4, 0x10, - 0x8c, 0x5a, 0x81, 0xfb, 0x1c, 0xd9, 0x55, 0x76, 0x4f, 0x29, 0x8e, 0xd1, 0xa5, 0x7a, 0xed, 0x39, - 0xb2, 0x8b, 0x15, 0x16, 0xfd, 0xd4, 0x80, 0x99, 0xcd, 0xfe, 0x7d, 0x9a, 0xcd, 0x49, 0x47, 0x5d, - 0x1e, 0xf6, 0xcc, 0x0e, 0xd8, 0xf2, 0xea, 0x79, 0x71, 0x6e, 0x07, 0x20, 0xf0, 0x41, 0x8a, 0xcd, - 0x5f, 0xe5, 0x61, 0x66, 0xd9, 0xeb, 0x86, 0x9c, 0xb0, 0x8c, 0x73, 0xdd, 0xf9, 0x28, 0xfa, 0x9e, - 0x01, 0xd3, 0xa4, 0xd5, 0x22, 0x36, 0x77, 0x77, 0xc8, 0x09, 0x06, 0xd1, 0xac, 0xd2, 0x3a, 0xbd, - 0xd2, 0x23, 0x1c, 0xf7, 0xa9, 0x43, 0xdf, 0x85, 0x73, 0x09, 0xac, 0x56, 0xaf, 0x7a, 0xd4, 0xde, - 0x8e, 0xe3, 0xe7, 0xb1, 0x61, 0x6d, 0xa8, 0xd5, 0x37, 0x08, 0x4f, 0x43, 0x78, 0xa5, 0x57, 0x2e, - 0xee, 0x57, 0x85, 0xae, 0xc0, 0x04, 0xa7, 0xdc, 0xf2, 0xe2, 0xe5, 0xe7, 0x2f, 0x1a, 0x97, 0x72, - 0xe9, 0xbd, 0xde, 0xd4, 0x70, 0x38, 0x43, 0x89, 0x16, 0x01, 0xe4, 0x73, 0xdd, 0x6a, 0x93, 0x70, - 0xb6, 0x20, 0xf9, 0x92, 0xfd, 0x6e, 0x26, 0x18, 0xac, 0x51, 0x09, 0xdf, 0xb6, 0xbb, 0x8c, 0x11, - 0x9f, 0x8b, 0xe7, 0xd9, 0x51, 0xc9, 0x94, 0xf8, 0xf6, 0x72, 0x8a, 0xc2, 0x3a, 0x9d, 0xf9, 0xa9, - 0x01, 0xa5, 0x95, 0xf6, 0xe7, 0xa0, 0xf2, 0xfc, 0xbd, 0x01, 0x67, 0xb5, 0x85, 0x9e, 0x42, 0xa2, - 0x7c, 0x23, 0x9b, 0x28, 0x87, 0x5e, 0xa1, 0x66, 0xed, 0x80, 0x2c, 0xf9, 0xe3, 0x1c, 0x4c, 0x6b, - 0x54, 0x51, 0x8a, 0x74, 0x00, 0x68, 0xb2, 0xef, 0x27, 0x7a, 0x86, 0x9a, 0xdc, 0x2f, 0xd2, 0xe4, - 0x01, 0x69, 0xd2, 0x83, 0xf3, 0x2b, 0xd7, 0xb9, 0x48, 0x77, 0xde, 0x8a, 0xcf, 0x5d, 0xbe, 0x8b, - 0x49, 0x8b, 0x30, 0xe2, 0xdb, 0x04, 0x5d, 0x84, 0xbc, 0x96, 0x26, 0x27, 0x94, 0xe8, 0xfc, 0x86, - 0x48, 0x91, 0x12, 0x83, 0x2a, 0x50, 0x14, 0xbf, 0x61, 0x60, 0xd9, 0x44, 0xe5, 0x99, 0x73, 0x8a, - 0xac, 0xb8, 0x11, 0x23, 0x70, 0x4a, 0x63, 0xfe, 0xcb, 0x80, 0x69, 0xa9, 0x7e, 0x29, 0x0c, 0xa9, - 0xed, 0x46, 0x19, 0xee, 0x54, 0xea, 0xa3, 0x69, 0x4b, 0x69, 0x54, 0xeb, 0x3f, 0x72, 0x29, 0x28, - 0xb9, 0x93, 0x4d, 0x4a, 0x2f, 0xf7, 0xa5, 0x1e, 0xf9, 0xb8, 0x4f, 0xa3, 0xf9, 0x41, 0x1e, 0x4a, - 0xda, 0xe6, 0xa3, 0x97, 0x21, 0x17, 0x50, 0x47, 0xad, 0x79, 0xe8, 0x1e, 0xaf, 0x4e, 0x9d, 0xd4, - 0x8c, 0x31, 0x51, 0x55, 0x08, 0x88, 0x90, 0x88, 0xde, 0x35, 0x60, 0x8a, 0x64, 0x4e, 0x55, 0x9e, - 0x4e, 0x69, 0x71, 0x75, 0xe8, 0x78, 0x3e, 0xd8, 0x37, 0xaa, 0x68, 0x7f, 0x6f, 0x7e, 0xaa, 0x07, - 0xd9, 0xa3, 0x12, 0x3d, 0x04, 0x39, 0x37, 0x88, 0xdc, 0x7a, 0xa2, 0x7a, 0x97, 0x30, 0xb0, 0x56, - 0x0f, 0x6f, 0xee, 0xcd, 0x17, 0x6b, 0x75, 0xd5, 0x78, 0x62, 0x41, 0x80, 0x5e, 0x87, 0x42, 0x40, - 0x19, 0x17, 0xc9, 0x46, 0x9c, 0xc8, 0xd7, 0x87, 0xb5, 0x51, 0x78, 0x9a, 0x53, 0xa7, 0x8c, 0xa7, - 0x37, 0x8e, 0x78, 0x0a, 0x71, 0x24, 0x16, 0xbd, 0x0a, 0x79, 0x9f, 0x3a, 0x44, 0xe6, 0xa4, 0xd2, - 0xe2, 0xd3, 0x43, 0x8b, 0xa7, 0x0e, 0x49, 0x17, 0x3e, 0x2e, 0x43, 0x40, 0x80, 0xa4, 0x50, 0xd4, - 0x86, 0xb1, 0x90, 0xb0, 0x1d, 0xd7, 0x8e, 0xd2, 0x57, 0x69, 0xf1, 0x1b, 0xc3, 0xca, 0x6f, 0x44, - 0xec, 0xa9, 0x8a, 0xd2, 0xfe, 0xde, 0xfc, 0x58, 0x0c, 0x8d, 0xa5, 0x9b, 0xbf, 0x36, 0x60, 0x2a, - 0xeb, 0x7b, 0xd9, 0xf0, 0x33, 0x0e, 0x0f, 0xbf, 0x24, 0xa2, 0x47, 0x06, 0x46, 0x74, 0x15, 0x72, - 0x5d, 0xd7, 0x91, 0xd5, 0x5f, 0xb1, 0xfa, 0x48, 0x52, 0xae, 0xd6, 0xae, 0xde, 0xdc, 0x9b, 0x7f, - 0x60, 0xd0, 0x98, 0x88, 0xef, 0x06, 0x24, 0x2c, 0xbf, 0x58, 0xbb, 0x8a, 0x05, 0xb3, 0xf9, 0x36, - 0x4c, 0x3c, 0xdb, 0x6c, 0xd6, 0xeb, 0x8c, 0x72, 0x6a, 0x53, 0x4f, 0x68, 0xdd, 0xa2, 0x21, 0xef, - 0xbd, 0x47, 0x9e, 0xa5, 0x21, 0xc7, 0x12, 0x23, 0x8a, 0xd5, 0x0e, 0xe1, 0x5b, 0xd4, 0xe9, 0x2d, - 0x56, 0xd7, 0x25, 0x14, 0x2b, 0xac, 0x90, 0x14, 0x58, 0x7c, 0x4b, 0x99, 0x97, 0x48, 0xaa, 0x5b, - 0x7c, 0x0b, 0x4b, 0x8c, 0xf9, 0xa1, 0x01, 0x63, 0xaa, 0x98, 0x41, 0x2f, 0x43, 0xde, 0x76, 0x1d, - 0xa6, 0xe2, 0xeb, 0x88, 0xe5, 0x53, 0xa2, 0x64, 0xb9, 0x76, 0x15, 0x63, 0x29, 0x10, 0xbd, 0x06, - 0xa3, 0xe4, 0xba, 0x4d, 0x02, 0xae, 0xee, 0x90, 0x23, 0x8a, 0x4e, 0x56, 0xb9, 0x22, 0x85, 0x61, - 0x25, 0xd4, 0xfc, 0xb7, 0x01, 0xa8, 0x56, 0xff, 0xfc, 0x5e, 0x93, 0x2d, 0x28, 0xc8, 0x0d, 0x42, - 0x0f, 0xc2, 0x88, 0x1b, 0xc8, 0xb5, 0x4e, 0x54, 0x67, 0xf6, 0xf7, 0xe6, 0x47, 0x6a, 0xf5, 0xec, - 0xf5, 0x31, 0xe2, 0x06, 0xa2, 0x62, 0x0d, 0x18, 0x69, 0xb9, 0xd7, 0xd7, 0x88, 0xdf, 0xe6, 0x5b, - 0xd2, 0x83, 0x0a, 0x69, 0x75, 0x55, 0xd7, 0x70, 0x38, 0x43, 0x69, 0xfe, 0xd6, 0x00, 0x58, 0xbb, - 0x9c, 0xb8, 0xe9, 0x2b, 0x90, 0xdf, 0xe2, 0x3c, 0x38, 0xea, 0x75, 0xac, 0xbb, 0x7c, 0x74, 0x4b, - 0x08, 0x08, 0x96, 0x32, 0xd1, 0x4b, 0x90, 0xe3, 0x5e, 0xa8, 0x2e, 0xe1, 0xa1, 0x33, 0x7c, 0x73, - 0xad, 0x91, 0x48, 0x96, 0x17, 0x7d, 0x73, 0xad, 0x81, 0x85, 0x40, 0xf3, 0x97, 0x06, 0xa0, 0xf5, - 0xae, 0x27, 0x9a, 0xa7, 0x90, 0xcb, 0xed, 0xab, 0xf9, 0x2d, 0x8a, 0x1e, 0x84, 0x82, 0xac, 0x23, - 0x55, 0xc8, 0x25, 0xd7, 0x62, 0x74, 0x28, 0x11, 0x0e, 0xbd, 0x0e, 0xf9, 0x80, 0x3a, 0x47, 0x1e, - 0x31, 0x66, 0xd2, 0x4f, 0x1a, 0x8a, 0xd4, 0x09, 0xb1, 0x94, 0x6b, 0xbe, 0x67, 0x40, 0x31, 0xb9, - 0x9a, 0x65, 0xe8, 0x52, 0x16, 0x5d, 0x02, 0x05, 0x9d, 0x9e, 0x71, 0x2c, 0x31, 0xb7, 0x71, 0x39, - 0x5d, 0x81, 0xf1, 0x40, 0xed, 0x83, 0xba, 0x02, 0xee, 0x4f, 0xba, 0x71, 0x05, 0xbf, 0xa9, 0xfd, - 0xc7, 0x09, 0xb5, 0xf9, 0xf7, 0x1c, 0x4c, 0x6e, 0x10, 0xfe, 0x16, 0x65, 0xdb, 0x75, 0xea, 0xb9, - 0xf6, 0xee, 0x29, 0x44, 0x53, 0x0b, 0x0a, 0xac, 0xeb, 0x91, 0x78, 0x83, 0x97, 0x86, 0xce, 0x3b, - 0xba, 0xbd, 0xb8, 0xeb, 0x91, 0xf4, 0x1c, 0xc5, 0x53, 0x88, 0x23, 0xf1, 0xe8, 0x69, 0x38, 0x6b, - 0x65, 0xa6, 0x4e, 0x51, 0xca, 0x2d, 0xca, 0x90, 0x39, 0x9b, 0x1d, 0x48, 0x85, 0xb8, 0x97, 0x16, - 0x5d, 0x12, 0x9b, 0xea, 0x52, 0x26, 0x8a, 0x04, 0xd1, 0xed, 0x19, 0xd5, 0x89, 0x68, 0x43, 0x23, - 0x18, 0x4e, 0xb0, 0xe8, 0x51, 0x98, 0xe0, 0x2e, 0x61, 0x31, 0x46, 0xe6, 0xd3, 0x42, 0x75, 0x5a, - 0xf6, 0x85, 0x1a, 0x1c, 0x67, 0xa8, 0x50, 0x08, 0xc5, 0x90, 0x76, 0x99, 0x4c, 0x70, 0x2a, 0x45, - 0x5e, 0x3b, 0xde, 0x56, 0x24, 0x5e, 0x37, 0x29, 0x12, 0x5d, 0x23, 0x16, 0x8e, 0x53, 0x3d, 0xe6, - 0x1f, 0x0d, 0x38, 0x97, 0x61, 0x3a, 0x85, 0xd6, 0x69, 0x33, 0xdb, 0x3a, 0x3d, 0x7d, 0xac, 0x45, - 0x0e, 0x68, 0x9e, 0xfe, 0x61, 0xc0, 0xf9, 0x0c, 0x9d, 0xa8, 0x44, 0x1a, 0xdc, 0xe2, 0xdd, 0x10, - 0x3d, 0x0c, 0xe3, 0xa2, 0x22, 0xd9, 0x38, 0x60, 0xb2, 0xb5, 0xa1, 0xe0, 0x38, 0xa1, 0x10, 0xed, - 0xba, 0x7a, 0xa3, 0xe3, 0x52, 0x5f, 0xc6, 0x9c, 0xd6, 0xae, 0xaf, 0x26, 0x18, 0xac, 0x51, 0xa1, - 0x6f, 0x02, 0x62, 0xc4, 0xf2, 0xdc, 0xb7, 0xe5, 0xe3, 0x35, 0xcb, 0xf5, 0xba, 0x8c, 0xc8, 0x48, - 0x1c, 0xaf, 0xde, 0xab, 0x78, 0x11, 0xee, 0xa3, 0xc0, 0x07, 0x70, 0xa1, 0x2f, 0xc3, 0x58, 0x87, - 0x84, 0xa1, 0x68, 0xfb, 0xf3, 0xd2, 0xd8, 0xb3, 0x4a, 0xc0, 0xd8, 0x7a, 0x04, 0xc6, 0x31, 0x5e, - 0xbe, 0xa9, 0xc8, 0x2c, 0xba, 0x4e, 0x08, 0x43, 0x97, 0x61, 0xd2, 0xd2, 0x5e, 0x5f, 0x84, 0xb3, - 0x86, 0x74, 0xfa, 0x73, 0xfb, 0x7b, 0xf3, 0x93, 0xfa, 0x7b, 0x8d, 0x10, 0x67, 0xe9, 0x10, 0x81, - 0x71, 0x37, 0x50, 0x93, 0x95, 0xe8, 0xa8, 0x2e, 0x0f, 0x9f, 0xbf, 0x25, 0x7f, 0xba, 0xc1, 0xc9, - 0x48, 0x25, 0x11, 0x8d, 0xe6, 0xa1, 0xd0, 0x7a, 0xd3, 0xf1, 0xe3, 0x60, 0x2c, 0x8a, 0xb3, 0xbc, - 0xf6, 0xc2, 0xd5, 0x8d, 0x10, 0x47, 0x70, 0xc4, 0x01, 0x38, 0x55, 0x65, 0x5e, 0x5c, 0xfb, 0x1e, - 0xbf, 0x78, 0xd4, 0x46, 0x2e, 0xb1, 0x6c, 0xac, 0xe9, 0x11, 0xb7, 0x85, 0x67, 0x6d, 0x12, 0xaf, - 0xe6, 0x10, 0x51, 0xa5, 0xbb, 0x72, 0x56, 0x93, 0xbb, 0x34, 0x19, 0xdd, 0x16, 0x6b, 0x59, 0x14, - 0xee, 0xa5, 0x35, 0x3f, 0x35, 0xe0, 0x9e, 0x83, 0xa3, 0x11, 0x3d, 0x06, 0x79, 0x51, 0x08, 0x2a, - 0xdf, 0x7b, 0x20, 0xbe, 0xbf, 0x9b, 0xbb, 0x01, 0xb9, 0xb9, 0x37, 0x9f, 0x3d, 0x41, 0x01, 0xc4, - 0x92, 0x7c, 0xe8, 0x1e, 0x32, 0xc9, 0x13, 0xb9, 0xc3, 0x8a, 0xd8, 0xfc, 0x71, 0x8a, 0xd8, 0x0f, - 0x47, 0x7b, 0x9c, 0x4e, 0xdc, 0xb9, 0xe8, 0x29, 0x28, 0x3a, 0x2e, 0x23, 0xb6, 0x0c, 0x9a, 0x68, - 0xa1, 0x73, 0xb1, 0xb1, 0x57, 0x63, 0xc4, 0x4d, 0xfd, 0x01, 0xa7, 0x0c, 0xc8, 0x86, 0x7c, 0x8b, - 0xd1, 0x8e, 0x2a, 0x03, 0x8e, 0x97, 0x10, 0x44, 0x0c, 0xa4, 0x8b, 0xbf, 0xc6, 0x68, 0x07, 0x4b, - 0xe1, 0xe8, 0x35, 0x18, 0xe1, 0x54, 0x8d, 0x6f, 0x4f, 0x40, 0x05, 0x28, 0x15, 0x23, 0x4d, 0x8a, - 0x47, 0x38, 0x15, 0xd1, 0x13, 0x66, 0x7d, 0xf6, 0xf2, 0x11, 0x7d, 0x36, 0x8d, 0x9e, 0xc4, 0x51, - 0x13, 0xd1, 0x72, 0xf0, 0xde, 0x93, 0x67, 0xd2, 0x54, 0xdf, 0x97, 0x99, 0x5e, 0x82, 0x51, 0x2b, - 0x3a, 0x93, 0x51, 0x79, 0x26, 0xcf, 0xc8, 0x41, 0x77, 0x7c, 0x18, 0x8f, 0xdc, 0xe2, 0xb3, 0x02, - 0xe6, 0xa8, 0xaf, 0x09, 0x16, 0xca, 0xe2, 0x80, 0x23, 0x1e, 0xac, 0xa4, 0xa1, 0x27, 0x61, 0x92, - 0xf8, 0xd6, 0xa6, 0x47, 0xd6, 0x68, 0xbb, 0xed, 0xfa, 0xed, 0xd9, 0x31, 0x79, 0xd7, 0xdd, 0xad, - 0x4c, 0x99, 0x5c, 0xd1, 0x91, 0x38, 0x4b, 0x7b, 0x50, 0x5e, 0x1e, 0x1f, 0x22, 0x2f, 0xc7, 0x6e, - 0x5e, 0x1c, 0xe8, 0xe6, 0x6f, 0x42, 0xc9, 0x4b, 0xca, 0xd7, 0x70, 0x16, 0xe4, 0x69, 0x3c, 0x31, - 0xec, 0x69, 0xa4, 0x15, 0x70, 0x3a, 0x79, 0x4d, 0x61, 0x21, 0xd6, 0x75, 0x88, 0x63, 0xf1, 0x68, - 0x5b, 0xde, 0x12, 0xb3, 0xa5, 0x6c, 0x8e, 0x59, 0x53, 0x70, 0x9c, 0x50, 0x98, 0xef, 0xe7, 0x00, - 0x65, 0x3c, 0x4a, 0x64, 0xaa, 0x10, 0xbd, 0x6b, 0xc0, 0xa4, 0xaf, 0x83, 0x55, 0x32, 0x3e, 0xa9, - 0xb2, 0x20, 0x39, 0x9e, 0x2c, 0x3e, 0xab, 0x13, 0x05, 0x30, 0xc1, 0x99, 0xd5, 0x6a, 0xb9, 0xb6, - 0xb4, 0x4a, 0x05, 0xe5, 0xe3, 0xb7, 0xb0, 0x41, 0x7e, 0x13, 0x52, 0x8e, 0xbf, 0x09, 0x29, 0x37, - 0x35, 0x6e, 0x6d, 0x42, 0xae, 0x41, 0x71, 0x46, 0x03, 0x7a, 0xc7, 0x80, 0x69, 0x51, 0xb2, 0xe9, - 0x24, 0x6a, 0xe8, 0xf7, 0xc4, 0xed, 0xab, 0xc5, 0x3d, 0x12, 0xd2, 0xd6, 0xaa, 0x17, 0x83, 0xfb, - 0xb4, 0x99, 0x7f, 0x35, 0x60, 0xa6, 0xef, 0x44, 0xba, 0xa7, 0xf1, 0x72, 0xc5, 0x83, 0x82, 0xa8, - 0x3d, 0xe2, 0x94, 0xbb, 0x7a, 0xac, 0xb3, 0x4e, 0xab, 0x9e, 0xb4, 0x4e, 0x12, 0xb0, 0x10, 0x47, - 0x4a, 0xcc, 0x05, 0x98, 0xcc, 0x8c, 0x6d, 0x0e, 0x9f, 0x65, 0x9a, 0x1f, 0x14, 0x60, 0x3a, 0x96, - 0x1b, 0x36, 0xba, 0x9d, 0x8e, 0xc5, 0x4e, 0xa3, 0x4b, 0xf8, 0x81, 0x01, 0x67, 0x75, 0xc7, 0x74, - 0x93, 0x2d, 0xaa, 0x1e, 0x6b, 0x8b, 0x22, 0xdf, 0x38, 0xaf, 0x74, 0x9f, 0xdd, 0xc8, 0xaa, 0xc0, - 0xbd, 0x3a, 0xd1, 0x6f, 0x0c, 0xb8, 0x3f, 0xd2, 0xa2, 0x5e, 0xbe, 0xf5, 0x70, 0x28, 0x47, 0x3d, - 0x09, 0xa3, 0xfe, 0x5f, 0x19, 0x75, 0xff, 0xd2, 0x2d, 0xf4, 0xe1, 0x5b, 0x5a, 0x83, 0x7e, 0x61, - 0xc0, 0xdd, 0x11, 0x41, 0xaf, 0x9d, 0xf9, 0x13, 0xb3, 0xf3, 0x82, 0xb2, 0xf3, 0xee, 0xa5, 0x83, - 0x14, 0xe1, 0x83, 0xf5, 0x8b, 0x7e, 0xa7, 0x13, 0x77, 0xe4, 0xb2, 0xb4, 0x3a, 0x82, 0x31, 0xfd, - 0x2d, 0x7d, 0x5a, 0x13, 0x25, 0x38, 0x9c, 0xea, 0x31, 0x5f, 0x83, 0xbb, 0xea, 0x56, 0xdb, 0xf5, - 0x65, 0x89, 0xbd, 0x4a, 0xf8, 0xf3, 0x81, 0xf8, 0x13, 0x46, 0x03, 0xb3, 0x76, 0xe4, 0xf6, 0x39, - 0x7d, 0x60, 0xd6, 0x26, 0x58, 0x62, 0xd0, 0x83, 0x50, 0xf0, 0xdc, 0x8e, 0xcb, 0x55, 0x0b, 0x90, - 0x84, 0xd3, 0x9a, 0x00, 0xe2, 0x08, 0x67, 0x5a, 0x30, 0xa1, 0xb7, 0xfb, 0x77, 0xe2, 0xcd, 0xc0, - 0xef, 0x72, 0x10, 0xcf, 0x3c, 0xd1, 0xa3, 0x5a, 0x9f, 0x1f, 0xa9, 0x98, 0x3d, 0xbc, 0xc7, 0x47, - 0x1b, 0x6a, 0xc2, 0x30, 0x72, 0x48, 0x9c, 0x76, 0xb9, 0xeb, 0x95, 0xa3, 0x8f, 0xda, 0xca, 0x35, - 0x9f, 0x3f, 0xcf, 0x1a, 0x9c, 0xb9, 0x7e, 0x3b, 0x9a, 0xd9, 0x68, 0xf3, 0x88, 0x2f, 0xc1, 0x18, - 0xf1, 0xe5, 0xf0, 0x42, 0x56, 0x53, 0x85, 0x68, 0x2e, 0xbb, 0x12, 0x81, 0x70, 0x8c, 0x13, 0xfd, - 0xb3, 0x6b, 0x77, 0x02, 0x51, 0xd1, 0xca, 0x8a, 0xb3, 0x10, 0xf5, 0xcf, 0xb5, 0xe5, 0xf5, 0xba, - 0xac, 0x72, 0x13, 0x6c, 0x4c, 0xb9, 0x1c, 0xcf, 0xa2, 0x35, 0x4a, 0x01, 0xc3, 0x09, 0x56, 0x52, - 0xb6, 0x95, 0xcc, 0x51, 0x8d, 0x72, 0x35, 0x91, 0xa9, 0xb0, 0xe8, 0x8a, 0x7a, 0x31, 0xa9, 0x3a, - 0x1e, 0x59, 0xa0, 0x14, 0x7b, 0xde, 0x2d, 0xc6, 0xd3, 0xb2, 0x0c, 0xa5, 0x58, 0x5e, 0xc8, 0x6c, - 0xb9, 0xbc, 0xf1, 0x74, 0x79, 0x8d, 0x08, 0x84, 0x63, 0x1c, 0x2a, 0x03, 0x84, 0xcc, 0x56, 0xab, - 0x96, 0xc5, 0x48, 0xa1, 0x3a, 0x25, 0x6e, 0xb3, 0x46, 0x02, 0xc5, 0x1a, 0x85, 0x49, 0x60, 0xba, - 0xb7, 0x27, 0xb9, 0x13, 0xee, 0xf2, 0x7e, 0x1e, 0xce, 0x37, 0xba, 0x81, 0x38, 0xa8, 0xe8, 0xf3, - 0x89, 0x65, 0xea, 0x79, 0xaa, 0xcc, 0xbe, 0xf3, 0x97, 0xf6, 0xab, 0x50, 0x24, 0xd7, 0x03, 0x97, - 0x11, 0x67, 0x29, 0xf6, 0xb7, 0xaf, 0xdc, 0x9e, 0x8a, 0xa6, 0xdb, 0x21, 0xe9, 0xd2, 0x56, 0x62, - 0x21, 0x38, 0x95, 0x27, 0xf6, 0x22, 0x74, 0x7d, 0x9b, 0x08, 0x52, 0xd5, 0xe4, 0x24, 0x0c, 0x8d, - 0x18, 0x81, 0x53, 0x1a, 0xd1, 0x48, 0xb6, 0x92, 0x0f, 0x4e, 0xa4, 0x0f, 0x1e, 0xa1, 0x91, 0xec, - 0xfd, 0x70, 0x25, 0xdd, 0x81, 0x14, 0x86, 0x35, 0x3d, 0xe8, 0x27, 0x06, 0x4c, 0x59, 0xd9, 0x6f, - 0x46, 0xa2, 0x17, 0x2c, 0xeb, 0x47, 0x53, 0x3d, 0xe0, 0xfb, 0x97, 0xea, 0x3d, 0xca, 0x8e, 0xa9, - 0x9e, 0x8f, 0x47, 0x7a, 0x94, 0x9b, 0x9f, 0x19, 0x70, 0xdf, 0x00, 0x8f, 0x38, 0x85, 0xe1, 0x8f, - 0x97, 0x1d, 0xfe, 0x0c, 0x5d, 0xde, 0x0c, 0xb0, 0x7c, 0xc0, 0x18, 0xe8, 0xe7, 0x23, 0xf0, 0xc0, - 0x00, 0x8e, 0x23, 0x0f, 0x84, 0x9e, 0x84, 0xc9, 0xf8, 0xbf, 0x1e, 0x86, 0x69, 0x31, 0xad, 0x23, - 0x71, 0x96, 0x36, 0x56, 0x25, 0x2f, 0xac, 0x5c, 0xbf, 0xaa, 0xe8, 0xd2, 0x8a, 0x29, 0x84, 0x87, - 0xdb, 0xb4, 0x13, 0x78, 0x84, 0x93, 0xa8, 0x4b, 0x1f, 0x4f, 0x3d, 0x7c, 0x39, 0x46, 0xe0, 0x94, - 0x46, 0x24, 0x29, 0xc2, 0x18, 0x65, 0xd2, 0xc3, 0xb4, 0x79, 0xf6, 0x8a, 0x00, 0xe2, 0x08, 0x67, - 0xfe, 0xd3, 0x80, 0x0b, 0x03, 0x36, 0xe5, 0xd4, 0xaa, 0xdc, 0x9d, 0x6c, 0x95, 0xfb, 0xc2, 0x09, - 0xb9, 0xc1, 0xa1, 0xf5, 0xee, 0xc3, 0x50, 0xd2, 0x5e, 0x12, 0xa0, 0x0b, 0x90, 0x0b, 0x7d, 0xb7, - 0xf7, 0xa3, 0xb3, 0xc6, 0x46, 0x0d, 0x0b, 0x78, 0xb5, 0xf9, 0xd1, 0x8d, 0xb9, 0x33, 0x1f, 0xdf, - 0x98, 0x3b, 0xf3, 0xc9, 0x8d, 0xb9, 0x33, 0xef, 0xec, 0xcf, 0x19, 0x1f, 0xed, 0xcf, 0x19, 0x1f, - 0xef, 0xcf, 0x19, 0x9f, 0xec, 0xcf, 0x19, 0x7f, 0xde, 0x9f, 0x33, 0x7e, 0xf6, 0x97, 0xb9, 0x33, - 0xaf, 0x94, 0x87, 0xfb, 0x1a, 0xff, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x8d, 0x27, 0x1b, - 0xbe, 0x2f, 0x00, 0x00, + // 2862 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x1b, 0x4b, 0x6f, 0x24, 0xc5, + 0x79, 0xdb, 0x33, 0x63, 0x7b, 0xbe, 0x19, 0x7b, 0xbd, 0x65, 0x60, 0x1d, 0x60, 0xed, 0xa5, 0x49, + 0xd0, 0x26, 0x22, 0x33, 0xd8, 0x01, 0x76, 0xc3, 0x4b, 0xf1, 0x78, 0xbd, 0x66, 0x82, 0x6d, 0x86, + 0x9a, 0x01, 0x24, 0x08, 0x84, 0x76, 0x77, 0xcd, 0xb8, 0xb3, 0x3d, 0x5d, 0x4d, 0x75, 0x8d, 0x59, + 0x73, 0x88, 0x88, 0x48, 0x0e, 0xe4, 0x45, 0x94, 0x4b, 0xc4, 0x2d, 0xb7, 0x5c, 0xf2, 0x0b, 0x38, + 0x85, 0x43, 0x24, 0x8e, 0x44, 0x51, 0x14, 0x4e, 0x56, 0xd6, 0x51, 0x88, 0x38, 0xe4, 0x92, 0x5b, + 0x36, 0x8a, 0x14, 0x55, 0x75, 0xf5, 0x73, 0x66, 0xd6, 0x3b, 0xb6, 0xd7, 0x91, 0xc2, 0x9e, 0x3c, + 0xfd, 0xbd, 0xab, 0xea, 0xfb, 0xea, 0x7b, 0x74, 0x1b, 0x9e, 0x31, 0x5c, 0xce, 0x88, 0x51, 0xb1, + 0x69, 0x35, 0xf8, 0x55, 0xf5, 0xae, 0x76, 0xaa, 0x86, 0x67, 0xfb, 0x55, 0x93, 0xba, 0x9c, 0x51, + 0xc7, 0x73, 0x0c, 0x97, 0x54, 0x77, 0x16, 0xb7, 0x08, 0x37, 0x96, 0xaa, 0x1d, 0xe2, 0x12, 0x66, + 0x70, 0x62, 0x55, 0x3c, 0x46, 0x39, 0x45, 0x95, 0x80, 0xeb, 0xbb, 0x36, 0x55, 0xbf, 0x2a, 0xde, + 0xd5, 0x4e, 0x45, 0xf0, 0x57, 0x92, 0xfc, 0x15, 0xc5, 0x7f, 0xef, 0xa5, 0xe1, 0xfa, 0x7c, 0x6e, + 0x70, 0xbf, 0xba, 0xb3, 0x68, 0x38, 0xde, 0xb6, 0xb1, 0x98, 0xd5, 0x74, 0xef, 0xd7, 0x3b, 0x36, + 0xdf, 0xee, 0x6d, 0x55, 0x4c, 0xda, 0xad, 0x76, 0x68, 0x87, 0x56, 0x25, 0x78, 0xab, 0xd7, 0x96, + 0x4f, 0xf2, 0x41, 0xfe, 0x52, 0xe4, 0x8f, 0x5e, 0xbd, 0xe4, 0x4b, 0x2d, 0x9e, 0xdd, 0x35, 0xcc, + 0x6d, 0xdb, 0x25, 0x6c, 0x37, 0xd6, 0xd5, 0x25, 0xdc, 0xa8, 0xee, 0xf4, 0x2b, 0xa9, 0x0e, 0xe3, + 0x62, 0x3d, 0x97, 0xdb, 0x5d, 0xd2, 0xc7, 0xf0, 0xf8, 0x41, 0x0c, 0xbe, 0xb9, 0x4d, 0xba, 0x46, + 0x1f, 0xdf, 0x37, 0x86, 0xf1, 0xf5, 0xb8, 0xed, 0x54, 0x6d, 0x97, 0xfb, 0x9c, 0x65, 0x99, 0xf4, + 0xbf, 0x6b, 0x50, 0x5e, 0xb6, 0x2c, 0x46, 0x7c, 0x7f, 0x8d, 0xd1, 0x9e, 0x87, 0xde, 0x80, 0x49, + 0xb1, 0x12, 0xcb, 0xe0, 0xc6, 0x9c, 0x76, 0x5e, 0xbb, 0x50, 0x5a, 0x7a, 0xa4, 0x12, 0x08, 0xae, + 0x24, 0x05, 0xc7, 0x67, 0x22, 0xa8, 0x2b, 0x3b, 0x8b, 0x95, 0xe7, 0xb7, 0xbe, 0x47, 0x4c, 0xbe, + 0x41, 0xb8, 0x51, 0x43, 0x1f, 0xef, 0x2d, 0x9c, 0xda, 0xdf, 0x5b, 0x80, 0x18, 0x86, 0x23, 0xa9, + 0xa8, 0x07, 0xe5, 0x8e, 0x50, 0xb5, 0x41, 0xba, 0x5b, 0x84, 0xf9, 0x73, 0x63, 0xe7, 0x73, 0x17, + 0x4a, 0x4b, 0x4f, 0x8e, 0x78, 0xec, 0x95, 0xb5, 0x58, 0x46, 0xed, 0x2e, 0xa5, 0xb0, 0x9c, 0x00, + 0xfa, 0x38, 0xa5, 0x46, 0xff, 0xa3, 0x06, 0x33, 0xc9, 0x95, 0xae, 0xdb, 0x3e, 0x47, 0xdf, 0xe9, + 0x5b, 0x6d, 0xe5, 0xd6, 0x56, 0x2b, 0xb8, 0xe5, 0x5a, 0x67, 0x94, 0xea, 0xc9, 0x10, 0x92, 0x58, + 0xa9, 0x01, 0x05, 0x9b, 0x93, 0x6e, 0xb8, 0xc4, 0xa7, 0x46, 0x5d, 0x62, 0xd2, 0xdc, 0xda, 0x94, + 0x52, 0x54, 0xa8, 0x0b, 0x91, 0x38, 0x90, 0xac, 0xbf, 0x97, 0x83, 0x33, 0x49, 0xb2, 0x86, 0xc1, + 0xcd, 0xed, 0x13, 0x38, 0xc4, 0x1f, 0x6a, 0x70, 0xc6, 0xb0, 0x2c, 0x62, 0xad, 0x1d, 0xf3, 0x51, + 0x7e, 0x49, 0xa9, 0x15, 0xab, 0x4a, 0x4b, 0xc7, 0xfd, 0x0a, 0xd1, 0x8f, 0x35, 0x98, 0x65, 0xa4, + 0x4b, 0x77, 0x32, 0x86, 0xe4, 0x8e, 0x6e, 0xc8, 0x7d, 0xca, 0x90, 0x59, 0xdc, 0x2f, 0x1f, 0x0f, + 0x52, 0xaa, 0x7f, 0xae, 0xc1, 0xf4, 0xb2, 0xe7, 0x39, 0x36, 0xb1, 0x5a, 0xf4, 0xff, 0x3c, 0x9a, + 0xfe, 0xac, 0x01, 0x4a, 0xaf, 0xf5, 0x04, 0xe2, 0xc9, 0x4c, 0xc7, 0xd3, 0x33, 0x23, 0xc7, 0x53, + 0xca, 0xe0, 0x21, 0x11, 0xf5, 0x93, 0x1c, 0xcc, 0xa6, 0x09, 0xef, 0xc4, 0xd4, 0xff, 0x2e, 0xa6, + 0xde, 0x84, 0xd9, 0x9a, 0xe1, 0xdb, 0xe6, 0x72, 0x8f, 0x6f, 0x13, 0x97, 0xdb, 0xa6, 0xc1, 0x6d, + 0xea, 0xa2, 0x87, 0x61, 0xb2, 0xe7, 0x13, 0xe6, 0x1a, 0x5d, 0x22, 0x0f, 0xa3, 0x18, 0xfb, 0xcd, + 0x8b, 0x0a, 0x8e, 0x23, 0x0a, 0x41, 0xed, 0x19, 0xbe, 0xff, 0x16, 0x65, 0xd6, 0xdc, 0x58, 0x9a, + 0xba, 0xa1, 0xe0, 0x38, 0xa2, 0xd0, 0x17, 0x61, 0xa6, 0xd6, 0x73, 0x2d, 0x87, 0x5c, 0xb1, 0x1d, + 0xd2, 0x24, 0x6c, 0x87, 0x30, 0x74, 0x0e, 0x72, 0x3d, 0xe6, 0x28, 0x55, 0x25, 0xc5, 0x9c, 0x7b, + 0x11, 0xaf, 0x63, 0x01, 0xd7, 0xdf, 0x1f, 0x83, 0x73, 0x01, 0x4f, 0x40, 0x2f, 0xac, 0x5d, 0xa1, + 0x6e, 0xdb, 0xee, 0xf4, 0x58, 0x60, 0xf0, 0x63, 0x50, 0xda, 0x22, 0x06, 0x23, 0xac, 0x45, 0xaf, + 0x12, 0x57, 0x09, 0x9a, 0x55, 0x82, 0x4a, 0xb5, 0x18, 0x85, 0x93, 0x74, 0xe8, 0x21, 0x18, 0x37, + 0x3c, 0xfb, 0x39, 0xb2, 0xab, 0xec, 0x9e, 0x56, 0x1c, 0xe3, 0xcb, 0x8d, 0xfa, 0x73, 0x64, 0x17, + 0x2b, 0x2c, 0xfa, 0xb9, 0x06, 0xb3, 0x5b, 0xfd, 0xfb, 0x34, 0x97, 0x93, 0x8e, 0xba, 0x32, 0xea, + 0x99, 0x0d, 0xd8, 0xf2, 0xda, 0x59, 0x71, 0x6e, 0x03, 0x10, 0x78, 0x90, 0x62, 0xfd, 0xd7, 0x79, + 0x98, 0x5d, 0x71, 0x7a, 0x3e, 0x27, 0x2c, 0xe5, 0x5c, 0xb7, 0x3f, 0x8a, 0x7e, 0xa0, 0xc1, 0x0c, + 0x69, 0xb7, 0x89, 0xc9, 0xed, 0x1d, 0x72, 0x8c, 0x41, 0x34, 0xa7, 0xb4, 0xce, 0xac, 0x66, 0x84, + 0xe3, 0x3e, 0x75, 0xe8, 0xfb, 0x70, 0x26, 0x82, 0xd5, 0x1b, 0x35, 0x87, 0x9a, 0x57, 0xc3, 0xf8, + 0x79, 0x6c, 0x54, 0x1b, 0xea, 0x8d, 0x4d, 0xc2, 0xe3, 0x10, 0x5e, 0xcd, 0xca, 0xc5, 0xfd, 0xaa, + 0xd0, 0x25, 0x28, 0x73, 0xca, 0x0d, 0x27, 0x5c, 0x7e, 0xfe, 0xbc, 0x76, 0x21, 0x17, 0xdf, 0xeb, + 0xad, 0x04, 0x0e, 0xa7, 0x28, 0xd1, 0x12, 0x80, 0x7c, 0x6e, 0x18, 0x1d, 0xe2, 0xcf, 0x15, 0x24, + 0x5f, 0xb4, 0xdf, 0xad, 0x08, 0x83, 0x13, 0x54, 0xc2, 0xb7, 0xcd, 0x1e, 0x63, 0xc4, 0xe5, 0xe2, + 0x79, 0x6e, 0x5c, 0x32, 0x45, 0xbe, 0xbd, 0x12, 0xa3, 0x70, 0x92, 0x4e, 0xff, 0x4c, 0x83, 0xd2, + 0x6a, 0xe7, 0x0b, 0x50, 0x79, 0xfe, 0x41, 0x83, 0xd3, 0x89, 0x85, 0x9e, 0x40, 0xa2, 0x7c, 0x23, + 0x9d, 0x28, 0x47, 0x5e, 0x61, 0xc2, 0xda, 0x21, 0x59, 0xf2, 0xa7, 0x39, 0x98, 0x49, 0x50, 0x05, + 0x29, 0xd2, 0x02, 0xa0, 0xd1, 0xbe, 0x1f, 0xeb, 0x19, 0x26, 0xe4, 0xde, 0x49, 0x93, 0x03, 0xd2, + 0xa4, 0x03, 0x67, 0x57, 0xaf, 0x71, 0x91, 0xee, 0x9c, 0x55, 0x97, 0xdb, 0x7c, 0x17, 0x93, 0x36, + 0x61, 0xc4, 0x35, 0x09, 0x3a, 0x0f, 0xf9, 0x44, 0x9a, 0x2c, 0x2b, 0xd1, 0xf9, 0x4d, 0x91, 0x22, + 0x25, 0x06, 0x55, 0xa1, 0x28, 0xfe, 0xfa, 0x9e, 0x61, 0x12, 0x95, 0x67, 0xce, 0x28, 0xb2, 0xe2, + 0x66, 0x88, 0xc0, 0x31, 0x8d, 0xfe, 0x6f, 0x0d, 0x66, 0xa4, 0xfa, 0x65, 0xdf, 0xa7, 0xa6, 0x1d, + 0x64, 0xb8, 0x13, 0xa9, 0x8f, 0x66, 0x0c, 0xa5, 0x51, 0xad, 0xff, 0xd0, 0xa5, 0xa0, 0xe4, 0x8e, + 0x36, 0x29, 0xbe, 0xdc, 0x97, 0x33, 0xf2, 0x71, 0x9f, 0x46, 0xfd, 0xc3, 0x3c, 0x94, 0x12, 0x9b, + 0x8f, 0x5e, 0x86, 0x9c, 0x47, 0x2d, 0xb5, 0xe6, 0x91, 0x7b, 0xbc, 0x06, 0xb5, 0x62, 0x33, 0x26, + 0x44, 0x55, 0x21, 0x20, 0x42, 0x22, 0x7a, 0x57, 0x83, 0x69, 0x92, 0x3a, 0x55, 0x79, 0x3a, 0xa5, + 0xa5, 0xb5, 0x91, 0xe3, 0x79, 0xb0, 0x6f, 0xd4, 0xd0, 0xfe, 0xde, 0xc2, 0x74, 0x06, 0x99, 0x51, + 0x89, 0x1e, 0x82, 0x9c, 0xed, 0x05, 0x6e, 0x5d, 0xae, 0xdd, 0x25, 0x0c, 0xac, 0x37, 0xfc, 0x1b, + 0x7b, 0x0b, 0xc5, 0x7a, 0x43, 0x35, 0x9e, 0x58, 0x10, 0xa0, 0xd7, 0xa1, 0xe0, 0x51, 0xc6, 0x45, + 0xb2, 0x11, 0x27, 0xf2, 0xcd, 0x51, 0x6d, 0x14, 0x9e, 0x66, 0x35, 0x28, 0xe3, 0xf1, 0x8d, 0x23, + 0x9e, 0x7c, 0x1c, 0x88, 0x45, 0xaf, 0x42, 0xde, 0xa5, 0x16, 0x91, 0x39, 0xa9, 0xb4, 0xf4, 0xf4, + 0xc8, 0xe2, 0xa9, 0x45, 0xe2, 0x85, 0x4f, 0xca, 0x10, 0x10, 0x20, 0x29, 0x14, 0x75, 0x60, 0xc2, + 0x27, 0x6c, 0xc7, 0x36, 0x83, 0xf4, 0x55, 0x5a, 0xfa, 0xd6, 0xa8, 0xf2, 0x9b, 0x01, 0x7b, 0xac, + 0xa2, 0xb4, 0xbf, 0xb7, 0x30, 0x11, 0x42, 0x43, 0xe9, 0xfa, 0x07, 0x79, 0x28, 0xdf, 0x29, 0x88, + 0xee, 0x14, 0x44, 0x83, 0x0a, 0xa2, 0xdf, 0x68, 0x30, 0x9d, 0xbe, 0x97, 0xd2, 0x57, 0xb3, 0x76, + 0xf0, 0xd5, 0x1c, 0xdd, 0xf6, 0x63, 0x43, 0x6f, 0xfb, 0x1a, 0xe4, 0x7a, 0xb6, 0x25, 0x3b, 0x83, + 0x62, 0xed, 0x91, 0xa8, 0x95, 0xa9, 0x5f, 0xbe, 0xb1, 0xb7, 0xf0, 0xc0, 0xb0, 0x11, 0x22, 0xdf, + 0xf5, 0x88, 0x5f, 0x79, 0xb1, 0x7e, 0x19, 0x0b, 0x66, 0xfd, 0x6d, 0x28, 0x3f, 0xdb, 0x6a, 0x35, + 0x1a, 0x8c, 0x72, 0x6a, 0x52, 0x47, 0x68, 0xdd, 0xa6, 0x3e, 0xcf, 0xe6, 0x98, 0x67, 0xa9, 0xcf, + 0xb1, 0xc4, 0x88, 0x46, 0xa6, 0x4b, 0xf8, 0x36, 0xb5, 0xb2, 0x8d, 0xcc, 0x86, 0x84, 0x62, 0x85, + 0x15, 0x92, 0x3c, 0x83, 0x6f, 0x2b, 0xf3, 0x22, 0x49, 0x0d, 0x83, 0x6f, 0x63, 0x89, 0xd1, 0x3f, + 0xd2, 0x60, 0x42, 0x9d, 0x2b, 0x7a, 0x19, 0xf2, 0xa6, 0x6d, 0x31, 0x15, 0x38, 0x87, 0xf4, 0xa4, + 0x48, 0xc9, 0x4a, 0xfd, 0x32, 0xc6, 0x52, 0x20, 0x7a, 0x0d, 0xc6, 0xc9, 0x35, 0x93, 0x78, 0x5c, + 0x05, 0xca, 0x21, 0x45, 0x47, 0xab, 0x5c, 0x95, 0xc2, 0xb0, 0x12, 0xaa, 0xff, 0x47, 0x03, 0x54, + 0x6f, 0x7c, 0x71, 0x53, 0x68, 0x1b, 0x0a, 0x72, 0x83, 0xd0, 0x83, 0x30, 0x66, 0x7b, 0x72, 0xad, + 0xe5, 0xda, 0xec, 0xfe, 0xde, 0xc2, 0x58, 0xbd, 0x91, 0x4e, 0x2d, 0x63, 0xb6, 0x27, 0x82, 0xd7, + 0x63, 0xa4, 0x6d, 0x5f, 0x5b, 0x27, 0x6e, 0x87, 0x6f, 0x4b, 0x0f, 0x2a, 0xc4, 0xc1, 0xdb, 0x48, + 0xe0, 0x70, 0x8a, 0x52, 0xff, 0x9d, 0x06, 0xb0, 0x7e, 0x31, 0x72, 0xd3, 0x57, 0x20, 0xbf, 0xcd, + 0xb9, 0x77, 0xd8, 0x54, 0x9d, 0x74, 0xf9, 0x20, 0x83, 0x08, 0x08, 0x96, 0x32, 0xd1, 0x4b, 0x90, + 0xe3, 0x8e, 0xaf, 0x12, 0xf4, 0xc8, 0xf7, 0x6a, 0x6b, 0xbd, 0x19, 0x49, 0x96, 0x45, 0x40, 0x6b, + 0xbd, 0x89, 0x85, 0x40, 0xfd, 0x03, 0x0d, 0xd0, 0x46, 0xcf, 0x11, 0x8d, 0xb5, 0xcf, 0xe5, 0xf6, + 0xd5, 0xdd, 0x36, 0x45, 0x0f, 0x42, 0x41, 0xf6, 0x18, 0x2a, 0xe4, 0xa2, 0x94, 0x19, 0x1c, 0x4a, + 0x80, 0x43, 0xaf, 0x43, 0xde, 0xa3, 0xd6, 0xa1, 0xc7, 0xcf, 0xa9, 0xd2, 0x24, 0x0e, 0x45, 0x6a, + 0xf9, 0x58, 0xca, 0xd5, 0xdf, 0xd3, 0xa0, 0x18, 0xa5, 0x6d, 0x19, 0xba, 0x94, 0x05, 0x97, 0x40, + 0x21, 0x49, 0xcf, 0x38, 0x96, 0x98, 0x5b, 0xb8, 0x9c, 0x2e, 0xc1, 0xa4, 0xa7, 0xf6, 0x41, 0x5d, + 0x01, 0xf7, 0x47, 0x93, 0x1a, 0x05, 0xbf, 0x91, 0xf8, 0x8d, 0x23, 0x6a, 0xfd, 0x1f, 0x39, 0x98, + 0xda, 0x24, 0xfc, 0x2d, 0xca, 0xae, 0x36, 0xa8, 0x63, 0x9b, 0xbb, 0x27, 0x10, 0x4d, 0x6d, 0x28, + 0xb0, 0x9e, 0x43, 0xc2, 0x0d, 0x5e, 0x1e, 0xb9, 0x26, 0x49, 0xda, 0x8b, 0x7b, 0x0e, 0x89, 0xcf, + 0x51, 0x3c, 0xf9, 0x38, 0x10, 0x8f, 0x9e, 0x86, 0xd3, 0x46, 0x6a, 0x22, 0x19, 0xe4, 0xce, 0xa2, + 0x0c, 0x99, 0xd3, 0xe9, 0x61, 0xa5, 0x8f, 0xb3, 0xb4, 0xe8, 0x82, 0xd8, 0x54, 0x9b, 0x32, 0x51, + 0x40, 0x8a, 0xc4, 0xa7, 0xd5, 0xca, 0xc1, 0x86, 0x06, 0x30, 0x1c, 0x61, 0xd1, 0xa3, 0x50, 0xe6, + 0x36, 0x61, 0x21, 0x46, 0xa6, 0xbb, 0x42, 0x6d, 0x46, 0xa6, 0xc8, 0x04, 0x1c, 0xa7, 0xa8, 0x90, + 0x0f, 0x45, 0x9f, 0xf6, 0x98, 0x2c, 0x7e, 0x54, 0xf9, 0x74, 0xe5, 0x68, 0x5b, 0x11, 0x79, 0xdd, + 0x94, 0x48, 0x74, 0xcd, 0x50, 0x38, 0x8e, 0xf5, 0xe8, 0x7f, 0xd2, 0xe0, 0x4c, 0x8a, 0xe9, 0x04, + 0xda, 0xea, 0xad, 0x74, 0x5b, 0xfd, 0xf4, 0x91, 0x16, 0x39, 0xa4, 0xb1, 0xfe, 0xa7, 0x06, 0x67, + 0x53, 0x74, 0xa2, 0x4a, 0x6d, 0x72, 0x83, 0xf7, 0x7c, 0xf4, 0x30, 0x4c, 0x8a, 0x6a, 0x75, 0x73, + 0xc0, 0xd4, 0x73, 0x53, 0xc1, 0x71, 0x44, 0x21, 0x2a, 0x17, 0xf5, 0xb6, 0xcf, 0xa6, 0xae, 0x8c, + 0xb9, 0x44, 0xe5, 0xb2, 0x16, 0x61, 0x70, 0x82, 0x0a, 0x7d, 0x1b, 0x10, 0x23, 0x86, 0x63, 0xbf, + 0x2d, 0x1f, 0xaf, 0x18, 0xb6, 0xd3, 0x63, 0x44, 0x46, 0xe2, 0x64, 0xed, 0x5e, 0xc5, 0x8b, 0x70, + 0x1f, 0x05, 0x1e, 0xc0, 0x85, 0xbe, 0x0a, 0x13, 0x5d, 0xe2, 0xfb, 0xa2, 0x02, 0xca, 0x4b, 0x63, + 0x4f, 0x2b, 0x01, 0x13, 0x1b, 0x01, 0x18, 0x87, 0x78, 0xf9, 0x16, 0x2b, 0xb5, 0xe8, 0x06, 0x21, + 0x0c, 0x5d, 0x84, 0x29, 0x23, 0xf1, 0x6a, 0xcb, 0x9f, 0xd3, 0xa4, 0xd3, 0x9f, 0xd9, 0xdf, 0x5b, + 0x98, 0x4a, 0xbe, 0xf3, 0xf2, 0x71, 0x9a, 0x0e, 0x11, 0x98, 0xb4, 0x3d, 0x55, 0x64, 0x06, 0x47, + 0x75, 0x71, 0xf4, 0xfc, 0x2d, 0xf9, 0xe3, 0x0d, 0x8e, 0xaa, 0xcb, 0x48, 0x34, 0x5a, 0x80, 0x42, + 0xfb, 0x4d, 0xcb, 0x0d, 0x83, 0xb1, 0x28, 0xce, 0xf2, 0xca, 0x0b, 0x97, 0x37, 0x7d, 0x1c, 0xc0, + 0x11, 0x17, 0xb5, 0xa3, 0x6a, 0x01, 0xc2, 0xbe, 0xe8, 0xe8, 0x8d, 0x45, 0xa2, 0xfa, 0x0c, 0x65, + 0xe3, 0x84, 0x1e, 0x71, 0x5b, 0x38, 0xc6, 0x16, 0x71, 0xea, 0x16, 0x11, 0x1d, 0x9c, 0x2d, 0xcb, + 0xd6, 0xdc, 0x85, 0xa9, 0xe0, 0xb6, 0x58, 0x4f, 0xa3, 0x70, 0x96, 0x56, 0xff, 0x4c, 0x83, 0x7b, + 0x06, 0x47, 0x23, 0x7a, 0x0c, 0xf2, 0xa2, 0x10, 0x54, 0xbe, 0xf7, 0x40, 0x78, 0x7f, 0xb7, 0x76, + 0x3d, 0x72, 0x63, 0x6f, 0x21, 0x7d, 0x82, 0x02, 0x88, 0x25, 0xf9, 0xc8, 0xf3, 0x85, 0x28, 0x4f, + 0xe4, 0x0e, 0x2a, 0x62, 0xf3, 0x47, 0x29, 0x62, 0x3f, 0x1a, 0xcf, 0x38, 0x9d, 0xb8, 0x73, 0xd1, + 0x53, 0x50, 0xb4, 0x6c, 0x26, 0xda, 0x07, 0x1a, 0x8e, 0xe9, 0xe7, 0x43, 0x63, 0x2f, 0x87, 0x88, + 0x1b, 0xc9, 0x07, 0x1c, 0x33, 0x20, 0x13, 0xf2, 0x6d, 0x46, 0xbb, 0xaa, 0x0c, 0x38, 0x5a, 0x42, + 0x10, 0x31, 0x10, 0x2f, 0xfe, 0x0a, 0xa3, 0x5d, 0x2c, 0x85, 0xa3, 0xd7, 0x60, 0x8c, 0x53, 0x35, + 0xda, 0x3f, 0x06, 0x15, 0xa0, 0x54, 0x8c, 0xb5, 0x28, 0x1e, 0xe3, 0x54, 0x44, 0x8f, 0x9f, 0xf6, + 0xd9, 0x8b, 0x87, 0xf4, 0xd9, 0x38, 0x7a, 0x22, 0x47, 0x8d, 0x44, 0xcb, 0x97, 0x32, 0x99, 0x3c, + 0x13, 0xa7, 0xfa, 0xbe, 0xcc, 0xf4, 0x12, 0x8c, 0x1b, 0xc1, 0x99, 0x8c, 0xcb, 0x33, 0x79, 0x46, + 0xbe, 0x04, 0x09, 0x0f, 0xe3, 0x91, 0x9b, 0x7c, 0x72, 0xc2, 0x2c, 0xf5, 0xa5, 0xc9, 0x62, 0x45, + 0x1c, 0x70, 0xc0, 0x83, 0x95, 0x34, 0xf4, 0x24, 0x4c, 0x11, 0xd7, 0xd8, 0x72, 0xc8, 0x3a, 0xed, + 0x74, 0x6c, 0xb7, 0x33, 0x37, 0x21, 0xef, 0xba, 0xbb, 0x95, 0x29, 0x53, 0xab, 0x49, 0x24, 0x4e, + 0xd3, 0x0e, 0xca, 0xcb, 0x93, 0x23, 0xe4, 0xe5, 0xd0, 0xcd, 0x8b, 0x43, 0xdd, 0xfc, 0x4d, 0x28, + 0x39, 0x51, 0xf9, 0xea, 0xcf, 0x81, 0x3c, 0x8d, 0x27, 0x46, 0x3d, 0x8d, 0xb8, 0x02, 0x8e, 0x9b, + 0xd0, 0x18, 0xe6, 0xe3, 0xa4, 0x0e, 0x71, 0x2c, 0x0e, 0xed, 0xc8, 0x5b, 0x62, 0xae, 0x94, 0xce, + 0x31, 0xeb, 0x0a, 0x8e, 0x23, 0x0a, 0xfd, 0xfd, 0x1c, 0xa0, 0x94, 0x47, 0x89, 0x4c, 0xe5, 0xa3, + 0x77, 0x35, 0x98, 0x72, 0x93, 0x60, 0x95, 0x8c, 0x8f, 0xab, 0x2c, 0x88, 0x8e, 0x27, 0x8d, 0x4f, + 0xeb, 0x44, 0x1e, 0x94, 0x39, 0x33, 0xda, 0x6d, 0xdb, 0x94, 0x56, 0xa9, 0xa0, 0x7c, 0xfc, 0x26, + 0x36, 0xc8, 0xef, 0x85, 0x2a, 0xe1, 0xf7, 0x42, 0x95, 0x56, 0x82, 0x3b, 0x31, 0x2c, 0x48, 0x40, + 0x71, 0x4a, 0x03, 0x7a, 0x47, 0x83, 0x19, 0x51, 0xb2, 0x25, 0x49, 0xd4, 0x98, 0xe3, 0x89, 0x5b, + 0x57, 0x8b, 0x33, 0x12, 0xe2, 0xd6, 0x2a, 0x8b, 0xc1, 0x7d, 0xda, 0xf4, 0xbf, 0x69, 0x30, 0xdb, + 0x77, 0x22, 0xbd, 0x93, 0x98, 0x33, 0x39, 0x50, 0x10, 0xb5, 0x47, 0x98, 0x72, 0xd7, 0x8e, 0x74, + 0xd6, 0x71, 0xd5, 0x13, 0xd7, 0x49, 0x02, 0xe6, 0xe3, 0x40, 0x89, 0xbe, 0x08, 0x53, 0xa9, 0x91, + 0xde, 0xc1, 0x73, 0x6e, 0xfd, 0xc3, 0x02, 0xcc, 0x84, 0x72, 0xfd, 0x66, 0xaf, 0xdb, 0x35, 0xd8, + 0x49, 0x74, 0x09, 0x3f, 0xd2, 0xe0, 0x74, 0xd2, 0x31, 0xed, 0x68, 0x8b, 0x6a, 0x47, 0xda, 0xa2, + 0xc0, 0x37, 0xce, 0x2a, 0xdd, 0xa7, 0x37, 0xd3, 0x2a, 0x70, 0x56, 0x27, 0xfa, 0xad, 0x06, 0xf7, + 0x07, 0x5a, 0xd4, 0x8b, 0xd9, 0x0c, 0x87, 0x72, 0xd4, 0xe3, 0x30, 0xea, 0xcb, 0xca, 0xa8, 0xfb, + 0x97, 0x6f, 0xa2, 0x0f, 0xdf, 0xd4, 0x1a, 0xf4, 0x2b, 0x0d, 0xee, 0x0e, 0x08, 0xb2, 0x76, 0xe6, + 0x8f, 0xcd, 0xce, 0x73, 0xca, 0xce, 0xbb, 0x97, 0x07, 0x29, 0xc2, 0x83, 0xf5, 0x8b, 0x7e, 0xa7, + 0x1b, 0x76, 0xe4, 0xb2, 0xb4, 0x3a, 0x84, 0x31, 0xfd, 0x2d, 0x7d, 0x5c, 0x13, 0x45, 0x38, 0x1c, + 0xeb, 0xd1, 0x5f, 0x83, 0xbb, 0x1a, 0x46, 0xc7, 0x76, 0x65, 0x89, 0xbd, 0x46, 0xf8, 0xf3, 0x9e, + 0xf8, 0xe1, 0x07, 0x03, 0xb3, 0x4e, 0xe0, 0xf6, 0xb9, 0xe4, 0xc0, 0xac, 0x43, 0xb0, 0xc4, 0xa0, + 0x07, 0xa1, 0xe0, 0xd8, 0x5d, 0x9b, 0xab, 0x16, 0x20, 0x0a, 0xa7, 0x75, 0x01, 0xc4, 0x01, 0x4e, + 0x37, 0xa0, 0x9c, 0x6c, 0xf7, 0x6f, 0xc7, 0x5b, 0xa3, 0xdf, 0xe7, 0x20, 0x9c, 0x87, 0xa3, 0x47, + 0x13, 0x7d, 0x7e, 0xa0, 0x62, 0xee, 0xe0, 0x1e, 0x1f, 0x6d, 0xaa, 0x09, 0xc3, 0xd8, 0x01, 0x71, + 0xda, 0xe3, 0xb6, 0x53, 0x09, 0x3e, 0x78, 0xac, 0xd4, 0x5d, 0xfe, 0x3c, 0x6b, 0x72, 0x66, 0xbb, + 0x9d, 0x60, 0x66, 0x93, 0x98, 0x47, 0x7c, 0x05, 0x26, 0x88, 0x2b, 0x87, 0x17, 0xb2, 0x9a, 0x2a, + 0x04, 0x33, 0xfb, 0xd5, 0x00, 0x84, 0x43, 0x9c, 0xe8, 0x9f, 0x6d, 0xb3, 0xeb, 0x89, 0x8a, 0x56, + 0x56, 0x9c, 0x85, 0xa0, 0x7f, 0xae, 0xaf, 0x6c, 0x34, 0x64, 0x95, 0x1b, 0x61, 0x43, 0xca, 0x95, + 0xf0, 0x3d, 0x45, 0x82, 0x52, 0xc0, 0x70, 0x84, 0x95, 0x94, 0x1d, 0x25, 0x73, 0x3c, 0x41, 0xb9, + 0x16, 0xc9, 0x54, 0x58, 0x74, 0x49, 0xbd, 0xb4, 0x56, 0x1d, 0x8f, 0x2c, 0x50, 0x8a, 0x99, 0xf7, + 0xce, 0xe1, 0xb4, 0x2c, 0x45, 0x29, 0x96, 0xe7, 0x33, 0x53, 0x2e, 0x6f, 0x32, 0x5e, 0x5e, 0x33, + 0x00, 0xe1, 0x10, 0x87, 0x2a, 0x00, 0x3e, 0x33, 0xd5, 0xaa, 0x65, 0x31, 0x52, 0xa8, 0x4d, 0x8b, + 0xdb, 0xac, 0x19, 0x41, 0x71, 0x82, 0x42, 0x27, 0x30, 0x93, 0xed, 0x49, 0x6e, 0x87, 0xbb, 0xbc, + 0x9f, 0x87, 0xb3, 0xcd, 0x9e, 0x27, 0x0e, 0x2a, 0xf8, 0xb4, 0x66, 0x85, 0x3a, 0x8e, 0x2a, 0xb3, + 0x6f, 0xff, 0xa5, 0xfd, 0x2a, 0x14, 0xc9, 0x35, 0xcf, 0x66, 0xc4, 0x5a, 0x0e, 0xfd, 0xed, 0x6b, + 0xb7, 0xa6, 0xa2, 0x65, 0x77, 0x49, 0xbc, 0xb4, 0xd5, 0x50, 0x08, 0x8e, 0xe5, 0x89, 0xbd, 0xf0, + 0x6d, 0xd7, 0x24, 0x82, 0x54, 0x35, 0x39, 0x11, 0x43, 0x33, 0x44, 0xe0, 0x98, 0x46, 0x34, 0x92, + 0xed, 0xe8, 0x63, 0x24, 0xe9, 0x83, 0x87, 0x68, 0x24, 0xb3, 0x1f, 0x35, 0xc5, 0x3b, 0x10, 0xc3, + 0x70, 0x42, 0x0f, 0xfa, 0x99, 0x06, 0xd3, 0x46, 0xfa, 0x7b, 0xa2, 0xe0, 0xe5, 0xdb, 0xc6, 0xe1, + 0x54, 0x0f, 0xf9, 0x36, 0xaa, 0x76, 0x8f, 0xb2, 0x63, 0x3a, 0xf3, 0x61, 0x51, 0x46, 0xb9, 0xfe, + 0xb9, 0x06, 0xf7, 0x0d, 0xf1, 0x88, 0x13, 0x18, 0xfe, 0x38, 0xe9, 0xe1, 0xcf, 0xc8, 0xe5, 0xcd, + 0x10, 0xcb, 0x87, 0x8c, 0x81, 0x7e, 0x39, 0x06, 0x0f, 0x0c, 0xe1, 0x38, 0xf4, 0x40, 0xe8, 0x49, + 0x98, 0x0a, 0x7f, 0x27, 0xc3, 0x30, 0x2e, 0xa6, 0x93, 0x48, 0x9c, 0xa6, 0x0d, 0x55, 0xc9, 0x0b, + 0x2b, 0xd7, 0xaf, 0x2a, 0xb8, 0xb4, 0x42, 0x0a, 0xe1, 0xe1, 0x26, 0xed, 0x7a, 0x0e, 0xe1, 0x24, + 0xe8, 0xd2, 0x27, 0x63, 0x0f, 0x5f, 0x09, 0x11, 0x38, 0xa6, 0x11, 0x49, 0x8a, 0x30, 0x46, 0x99, + 0xf4, 0xb0, 0xc4, 0x3c, 0x7b, 0x55, 0x00, 0x71, 0x80, 0xd3, 0xff, 0xa5, 0xc1, 0xb9, 0x21, 0x9b, + 0x72, 0x62, 0x55, 0xee, 0x4e, 0xba, 0xca, 0x7d, 0xe1, 0x98, 0xdc, 0xe0, 0xc0, 0x7a, 0xf7, 0x61, + 0x28, 0x25, 0x5e, 0x12, 0xa0, 0x73, 0x90, 0xf3, 0x5d, 0x3b, 0xfb, 0x41, 0x62, 0x73, 0xb3, 0x8e, + 0x05, 0xbc, 0xd6, 0xfa, 0xf8, 0xfa, 0xfc, 0xa9, 0x4f, 0xae, 0xcf, 0x9f, 0xfa, 0xf4, 0xfa, 0xfc, + 0xa9, 0x77, 0xf6, 0xe7, 0xb5, 0x8f, 0xf7, 0xe7, 0xb5, 0x4f, 0xf6, 0xe7, 0xb5, 0x4f, 0xf7, 0xe7, + 0xb5, 0xbf, 0xec, 0xcf, 0x6b, 0xbf, 0xf8, 0xeb, 0xfc, 0xa9, 0x57, 0x2a, 0xa3, 0xfd, 0xa7, 0xc6, + 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x02, 0x8d, 0x03, 0xda, 0x31, 0x00, 0x00, } func (m *AddressGroup) Marshal() (dAtA []byte, err error) { @@ -2299,6 +2328,76 @@ func (m *GroupMember) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *GroupMembers) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GroupMembers) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GroupMembers) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.CurrentPage)) + i-- + dAtA[i] = 0x30 + i = encodeVarintGenerated(dAtA, i, uint64(m.TotalPages)) + i-- + dAtA[i] = 0x28 + i = encodeVarintGenerated(dAtA, i, uint64(m.TotalMembers)) + i-- + dAtA[i] = 0x20 + if len(m.EffectiveIPBlocks) > 0 { + for iNdEx := len(m.EffectiveIPBlocks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.EffectiveIPBlocks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.EffectiveMembers) > 0 { + for iNdEx := len(m.EffectiveMembers) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.EffectiveMembers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *GroupReference) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3979,6 +4078,32 @@ func (m *GroupMember) Size() (n int) { return n } +func (m *GroupMembers) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.EffectiveMembers) > 0 { + for _, e := range m.EffectiveMembers { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.EffectiveIPBlocks) > 0 { + for _, e := range m.EffectiveIPBlocks { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + n += 1 + sovGenerated(uint64(m.TotalMembers)) + n += 1 + sovGenerated(uint64(m.TotalPages)) + n += 1 + sovGenerated(uint64(m.CurrentPage)) + return n +} + func (m *GroupReference) Size() (n int) { if m == nil { return 0 @@ -4779,6 +4904,31 @@ func (this *GroupMember) String() string { }, "") return s } +func (this *GroupMembers) String() string { + if this == nil { + return "nil" + } + repeatedStringForEffectiveMembers := "[]GroupMember{" + for _, f := range this.EffectiveMembers { + repeatedStringForEffectiveMembers += strings.Replace(strings.Replace(f.String(), "GroupMember", "GroupMember", 1), `&`, ``, 1) + "," + } + repeatedStringForEffectiveMembers += "}" + repeatedStringForEffectiveIPBlocks := "[]IPNet{" + for _, f := range this.EffectiveIPBlocks { + repeatedStringForEffectiveIPBlocks += strings.Replace(strings.Replace(f.String(), "IPNet", "IPNet", 1), `&`, ``, 1) + "," + } + repeatedStringForEffectiveIPBlocks += "}" + s := strings.Join([]string{`&GroupMembers{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `EffectiveMembers:` + repeatedStringForEffectiveMembers + `,`, + `EffectiveIPBlocks:` + repeatedStringForEffectiveIPBlocks + `,`, + `TotalMembers:` + fmt.Sprintf("%v", this.TotalMembers) + `,`, + `TotalPages:` + fmt.Sprintf("%v", this.TotalPages) + `,`, + `CurrentPage:` + fmt.Sprintf("%v", this.CurrentPage) + `,`, + `}`, + }, "") + return s +} func (this *GroupReference) String() string { if this == nil { return "nil" @@ -7407,6 +7557,214 @@ func (m *GroupMember) Unmarshal(dAtA []byte) error { } return nil } +func (m *GroupMembers) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GroupMembers: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GroupMembers: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EffectiveMembers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EffectiveMembers = append(m.EffectiveMembers, GroupMember{}) + if err := m.EffectiveMembers[len(m.EffectiveMembers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EffectiveIPBlocks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EffectiveIPBlocks = append(m.EffectiveIPBlocks, IPNet{}) + if err := m.EffectiveIPBlocks[len(m.EffectiveIPBlocks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalMembers", wireType) + } + m.TotalMembers = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalMembers |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalPages", wireType) + } + m.TotalPages = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalPages |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentPage", wireType) + } + m.CurrentPage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentPage |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *GroupReference) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/apis/controlplane/v1beta2/generated.proto b/pkg/apis/controlplane/v1beta2/generated.proto index 017eba18c9d..e6e89d96d24 100644 --- a/pkg/apis/controlplane/v1beta2/generated.proto +++ b/pkg/apis/controlplane/v1beta2/generated.proto @@ -92,7 +92,7 @@ message BundleServerAuthConfiguration { optional BasicAuthentication basicAuthentication = 3; } -// ClusterGroupMembers is a list of GroupMember objects or ipBlocks that are currently selected by a ClusterGroup. +// ClusterGroupMembers is a list of GroupMember objects or IPBlocks that are currently selected by a ClusterGroup. message ClusterGroupMembers { optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; @@ -170,6 +170,21 @@ message GroupMember { optional ServiceReference service = 6; } +// GroupMembers is a list of GroupMember objects or IPBlocks that are currently selected by a Group. +message GroupMembers { + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + repeated GroupMember effectiveMembers = 2; + + repeated IPNet effectiveIPBlocks = 3; + + optional int64 totalMembers = 4; + + optional int64 totalPages = 5; + + optional int64 currentPage = 6; +} + message GroupReference { // Namespace of the Group. Empty for ClusterGroup. optional string namespace = 1; diff --git a/pkg/apis/controlplane/v1beta2/register.go b/pkg/apis/controlplane/v1beta2/register.go index bc1998f5ada..e90252dfa8f 100644 --- a/pkg/apis/controlplane/v1beta2/register.go +++ b/pkg/apis/controlplane/v1beta2/register.go @@ -71,6 +71,7 @@ func addKnownTypes(scheme *runtime.Scheme) error { &NetworkPolicyStatus{}, &NodeStatsSummary{}, &ClusterGroupMembers{}, + &GroupMembers{}, &PaginationGetOptions{}, &GroupAssociation{}, &IPGroupAssociation{}, diff --git a/pkg/apis/controlplane/v1beta2/types.go b/pkg/apis/controlplane/v1beta2/types.go index 6e9a7372867..8eae3c3cc4e 100644 --- a/pkg/apis/controlplane/v1beta2/types.go +++ b/pkg/apis/controlplane/v1beta2/types.go @@ -98,7 +98,7 @@ type GroupMember struct { // +genclient:onlyVerbs=get // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// ClusterGroupMembers is a list of GroupMember objects or ipBlocks that are currently selected by a ClusterGroup. +// ClusterGroupMembers is a list of GroupMember objects or IPBlocks that are currently selected by a ClusterGroup. type ClusterGroupMembers struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -109,6 +109,21 @@ type ClusterGroupMembers struct { CurrentPage int64 `json:"currentPage" protobuf:"varint,6,opt,name=currentPage"` } +// +genclient +// +genclient:onlyVerbs=get +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GroupMembers is a list of GroupMember objects or IPBlocks that are currently selected by a Group. +type GroupMembers struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + EffectiveMembers []GroupMember `json:"effectiveMembers" protobuf:"bytes,2,rep,name=effectiveMembers"` + EffectiveIPBlocks []IPNet `json:"effectiveIPBlocks" protobuf:"bytes,3,rep,name=effectiveIPBlocks"` + TotalMembers int64 `json:"totalMembers" protobuf:"varint,4,opt,name=totalMembers"` + TotalPages int64 `json:"totalPages" protobuf:"varint,5,opt,name=totalPages"` + CurrentPage int64 `json:"currentPage" protobuf:"varint,6,opt,name=currentPage"` +} + // +k8s:conversion-gen:explicit-from=net/url.Values // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/controlplane/v1beta2/zz_generated.conversion.go b/pkg/apis/controlplane/v1beta2/zz_generated.conversion.go index 77f7128878a..fe025322eb6 100644 --- a/pkg/apis/controlplane/v1beta2/zz_generated.conversion.go +++ b/pkg/apis/controlplane/v1beta2/zz_generated.conversion.go @@ -199,6 +199,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*GroupMembers)(nil), (*controlplane.GroupMembers)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_GroupMembers_To_controlplane_GroupMembers(a.(*GroupMembers), b.(*controlplane.GroupMembers), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*controlplane.GroupMembers)(nil), (*GroupMembers)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_controlplane_GroupMembers_To_v1beta2_GroupMembers(a.(*controlplane.GroupMembers), b.(*GroupMembers), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*GroupReference)(nil), (*controlplane.GroupReference)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta2_GroupReference_To_controlplane_GroupReference(a.(*GroupReference), b.(*controlplane.GroupReference), scope) }); err != nil { @@ -1111,6 +1121,56 @@ func Convert_controlplane_GroupMember_To_v1beta2_GroupMember(in *controlplane.Gr return autoConvert_controlplane_GroupMember_To_v1beta2_GroupMember(in, out, s) } +func autoConvert_v1beta2_GroupMembers_To_controlplane_GroupMembers(in *GroupMembers, out *controlplane.GroupMembers, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if in.EffectiveMembers != nil { + in, out := &in.EffectiveMembers, &out.EffectiveMembers + *out = make([]controlplane.GroupMember, len(*in)) + for i := range *in { + if err := Convert_v1beta2_GroupMember_To_controlplane_GroupMember(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.EffectiveMembers = nil + } + out.EffectiveIPBlocks = *(*[]controlplane.IPNet)(unsafe.Pointer(&in.EffectiveIPBlocks)) + out.TotalMembers = in.TotalMembers + out.TotalPages = in.TotalPages + out.CurrentPage = in.CurrentPage + return nil +} + +// Convert_v1beta2_GroupMembers_To_controlplane_GroupMembers is an autogenerated conversion function. +func Convert_v1beta2_GroupMembers_To_controlplane_GroupMembers(in *GroupMembers, out *controlplane.GroupMembers, s conversion.Scope) error { + return autoConvert_v1beta2_GroupMembers_To_controlplane_GroupMembers(in, out, s) +} + +func autoConvert_controlplane_GroupMembers_To_v1beta2_GroupMembers(in *controlplane.GroupMembers, out *GroupMembers, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if in.EffectiveMembers != nil { + in, out := &in.EffectiveMembers, &out.EffectiveMembers + *out = make([]GroupMember, len(*in)) + for i := range *in { + if err := Convert_controlplane_GroupMember_To_v1beta2_GroupMember(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.EffectiveMembers = nil + } + out.EffectiveIPBlocks = *(*[]IPNet)(unsafe.Pointer(&in.EffectiveIPBlocks)) + out.TotalMembers = in.TotalMembers + out.TotalPages = in.TotalPages + out.CurrentPage = in.CurrentPage + return nil +} + +// Convert_controlplane_GroupMembers_To_v1beta2_GroupMembers is an autogenerated conversion function. +func Convert_controlplane_GroupMembers_To_v1beta2_GroupMembers(in *controlplane.GroupMembers, out *GroupMembers, s conversion.Scope) error { + return autoConvert_controlplane_GroupMembers_To_v1beta2_GroupMembers(in, out, s) +} + func autoConvert_v1beta2_GroupReference_To_controlplane_GroupReference(in *GroupReference, out *controlplane.GroupReference, s conversion.Scope) error { out.Namespace = in.Namespace out.Name = in.Name diff --git a/pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go b/pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go index 672b6e0d825..86e63a1a0db 100644 --- a/pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go +++ b/pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go @@ -536,6 +536,46 @@ func (in *GroupMember) DeepCopy() *GroupMember { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupMembers) DeepCopyInto(out *GroupMembers) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.EffectiveMembers != nil { + in, out := &in.EffectiveMembers, &out.EffectiveMembers + *out = make([]GroupMember, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EffectiveIPBlocks != nil { + in, out := &in.EffectiveIPBlocks, &out.EffectiveIPBlocks + *out = make([]IPNet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupMembers. +func (in *GroupMembers) DeepCopy() *GroupMembers { + if in == nil { + return nil + } + out := new(GroupMembers) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GroupMembers) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GroupReference) DeepCopyInto(out *GroupReference) { *out = *in diff --git a/pkg/apis/controlplane/zz_generated.deepcopy.go b/pkg/apis/controlplane/zz_generated.deepcopy.go index 08e0944de99..4b8b67218a2 100644 --- a/pkg/apis/controlplane/zz_generated.deepcopy.go +++ b/pkg/apis/controlplane/zz_generated.deepcopy.go @@ -536,6 +536,46 @@ func (in *GroupMember) DeepCopy() *GroupMember { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupMembers) DeepCopyInto(out *GroupMembers) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.EffectiveMembers != nil { + in, out := &in.EffectiveMembers, &out.EffectiveMembers + *out = make([]GroupMember, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EffectiveIPBlocks != nil { + in, out := &in.EffectiveIPBlocks, &out.EffectiveIPBlocks + *out = make([]IPNet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupMembers. +func (in *GroupMembers) DeepCopy() *GroupMembers { + if in == nil { + return nil + } + out := new(GroupMembers) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GroupMembers) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GroupReference) DeepCopyInto(out *GroupReference) { *out = *in diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 865a8b87b08..697d4a451bf 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -49,6 +49,7 @@ import ( "antrea.io/antrea/pkg/apiserver/registry/networkpolicy/appliedtogroup" "antrea.io/antrea/pkg/apiserver/registry/networkpolicy/clustergroupmember" "antrea.io/antrea/pkg/apiserver/registry/networkpolicy/groupassociation" + "antrea.io/antrea/pkg/apiserver/registry/networkpolicy/groupmember" "antrea.io/antrea/pkg/apiserver/registry/networkpolicy/ipgroupassociation" "antrea.io/antrea/pkg/apiserver/registry/networkpolicy/networkpolicy" "antrea.io/antrea/pkg/apiserver/registry/stats/antreaclusternetworkpolicystats" @@ -192,6 +193,7 @@ func installAPIGroup(s *APIServer, c completedConfig) error { networkPolicyStorage := networkpolicy.NewREST(c.extraConfig.networkPolicyStore) networkPolicyStatusStorage := networkpolicy.NewStatusREST(c.extraConfig.networkPolicyStatusController) clusterGroupMembershipStorage := clustergroupmember.NewREST(c.extraConfig.networkPolicyController) + groupMembershipStorage := groupmember.NewREST(c.extraConfig.networkPolicyController) groupAssociationStorage := groupassociation.NewREST(c.extraConfig.networkPolicyController) ipGroupAssociationStorage := ipgroupassociation.NewREST(c.extraConfig.podInformer, c.extraConfig.eeInformer, c.extraConfig.networkPolicyController, c.extraConfig.networkPolicyController) nodeStatsSummaryStorage := nodestatssummary.NewREST(c.extraConfig.statsAggregator) @@ -208,6 +210,7 @@ func installAPIGroup(s *APIServer, c completedConfig) error { cpv1beta2Storage["groupassociations"] = groupAssociationStorage cpv1beta2Storage["ipgroupassociations"] = ipGroupAssociationStorage cpv1beta2Storage["clustergroupmembers"] = clusterGroupMembershipStorage + cpv1beta2Storage["groupmembers"] = groupMembershipStorage cpv1beta2Storage["egressgroups"] = egressGroupStorage cpv1beta2Storage["supportbundlecollections"] = bundleCollectionStorage cpv1beta2Storage["supportbundlecollections/status"] = bundleCollectionStatusStorage diff --git a/pkg/apiserver/openapi/zz_generated.openapi.go b/pkg/apiserver/openapi/zz_generated.openapi.go index 5a2eb174d2e..34f4fce09d1 100644 --- a/pkg/apiserver/openapi/zz_generated.openapi.go +++ b/pkg/apiserver/openapi/zz_generated.openapi.go @@ -46,6 +46,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "antrea.io/antrea/pkg/apis/controlplane/v1beta2.ExternalEntityReference": schema_pkg_apis_controlplane_v1beta2_ExternalEntityReference(ref), "antrea.io/antrea/pkg/apis/controlplane/v1beta2.GroupAssociation": schema_pkg_apis_controlplane_v1beta2_GroupAssociation(ref), "antrea.io/antrea/pkg/apis/controlplane/v1beta2.GroupMember": schema_pkg_apis_controlplane_v1beta2_GroupMember(ref), + "antrea.io/antrea/pkg/apis/controlplane/v1beta2.GroupMembers": schema_pkg_apis_controlplane_v1beta2_GroupMembers(ref), "antrea.io/antrea/pkg/apis/controlplane/v1beta2.GroupReference": schema_pkg_apis_controlplane_v1beta2_GroupReference(ref), "antrea.io/antrea/pkg/apis/controlplane/v1beta2.HTTPProtocol": schema_pkg_apis_controlplane_v1beta2_HTTPProtocol(ref), "antrea.io/antrea/pkg/apis/controlplane/v1beta2.IPBlock": schema_pkg_apis_controlplane_v1beta2_IPBlock(ref), @@ -818,7 +819,7 @@ func schema_pkg_apis_controlplane_v1beta2_ClusterGroupMembers(ref common.Referen return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "ClusterGroupMembers is a list of GroupMember objects or ipBlocks that are currently selected by a ClusterGroup.", + Description: "ClusterGroupMembers is a list of GroupMember objects or IPBlocks that are currently selected by a ClusterGroup.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "kind": { @@ -1192,6 +1193,89 @@ func schema_pkg_apis_controlplane_v1beta2_GroupMember(ref common.ReferenceCallba } } +func schema_pkg_apis_controlplane_v1beta2_GroupMembers(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "GroupMembers is a list of GroupMember objects or IPBlocks that are currently selected by a Group.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "effectiveMembers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("antrea.io/antrea/pkg/apis/controlplane/v1beta2.GroupMember"), + }, + }, + }, + }, + }, + "effectiveIPBlocks": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("antrea.io/antrea/pkg/apis/controlplane/v1beta2.IPNet"), + }, + }, + }, + }, + }, + "totalMembers": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "totalPages": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "currentPage": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + }, + Required: []string{"effectiveMembers", "effectiveIPBlocks", "totalMembers", "totalPages", "currentPage"}, + }, + }, + Dependencies: []string{ + "antrea.io/antrea/pkg/apis/controlplane/v1beta2.GroupMember", "antrea.io/antrea/pkg/apis/controlplane/v1beta2.IPNet", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + func schema_pkg_apis_controlplane_v1beta2_GroupReference(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/apiserver/registry/networkpolicy/clustergroupmember/rest.go b/pkg/apiserver/registry/networkpolicy/clustergroupmember/rest.go index d072f0db2c6..566b2a5b407 100644 --- a/pkg/apiserver/registry/networkpolicy/clustergroupmember/rest.go +++ b/pkg/apiserver/registry/networkpolicy/clustergroupmember/rest.go @@ -27,7 +27,7 @@ import ( ) type REST struct { - querier groupMembershipQuerier + querier GroupMembershipQuerier } var ( @@ -37,11 +37,11 @@ var ( ) // NewREST returns a REST object that will work against API services. -func NewREST(querier groupMembershipQuerier) *REST { +func NewREST(querier GroupMembershipQuerier) *REST { return &REST{querier} } -type groupMembershipQuerier interface { +type GroupMembershipQuerier interface { GetGroupMembers(name string) (controlplane.GroupMemberSet, []controlplane.IPBlock, error) } @@ -53,87 +53,87 @@ func (r *REST) Destroy() { } func (r *REST) Get(ctx context.Context, name string, options runtime.Object) (runtime.Object, error) { - groupMembers, ipBlocks, err := r.querier.GetGroupMembers(name) + var err error + memberList := &controlplane.ClusterGroupMembers{} + memberList.Name = name + memberList.EffectiveMembers, memberList.EffectiveIPBlocks, memberList.TotalMembers, memberList.TotalPages, memberList.CurrentPage, err = GetPaginatedMembers(r.querier, name, options) + return memberList, err +} + +// NewGetOptions returns the default options for Get, so options object is never nil. +func (r *REST) NewGetOptions() (runtime.Object, bool, string) { + return &controlplane.PaginationGetOptions{}, false, "" +} + +func (r *REST) NamespaceScoped() bool { + return false +} + +func GetPaginatedMembers(querier GroupMembershipQuerier, name string, options runtime.Object) (members []controlplane.GroupMember, ipNets []controlplane.IPNet, totalMembers, totalPages, currentPage int64, err error) { + groupMembers, ipBlocks, err := querier.GetGroupMembers(name) if err != nil { - return nil, errors.NewInternalError(err) + return nil, nil, 0, 0, 0, errors.NewInternalError(err) } // Retrieve options used for pagination. getOptions, ok := options.(*controlplane.PaginationGetOptions) if !ok || getOptions == nil { - return nil, errors.NewInternalError(fmt.Errorf("received error while retrieving options for pagination")) + return nil, nil, 0, 0, 0, errors.NewInternalError(fmt.Errorf("received error while retrieving options for pagination")) } - memberList := &controlplane.ClusterGroupMembers{} if len(ipBlocks) > 0 { - effectiveIPBlocks := make([]controlplane.IPNet, 0, len(ipBlocks)) + ipNets = make([]controlplane.IPNet, 0, len(ipBlocks)) for _, ipb := range ipBlocks { // ClusterGroup ipBlock does not support Except slices, so no need to generate an effective // list of IPs by removing Except slices from allowed CIDR. - effectiveIPBlocks = append(effectiveIPBlocks, ipb.CIDR) + ipNets = append(ipNets, ipb.CIDR) } - memberList.EffectiveIPBlocks = effectiveIPBlocks } if len(groupMembers) > 0 { - effectiveMembers := make([]controlplane.GroupMember, 0, len(groupMembers)) + members = make([]controlplane.GroupMember, 0, len(groupMembers)) for _, member := range groupMembers { - effectiveMembers = append(effectiveMembers, *member) + members = append(members, *member) } - memberList.EffectiveMembers = effectiveMembers } - memberList.Name = name - memberList.TotalMembers = int64(len(memberList.EffectiveMembers)) - err = paginateMemberList(memberList, getOptions) - return memberList, err -} - -// NewGetOptions returns the default options for Get, so options object is never nil. -func (r *REST) NewGetOptions() (runtime.Object, bool, string) { - return &controlplane.PaginationGetOptions{}, false, "" -} - -func (r *REST) NamespaceScoped() bool { - return false + totalMembers = int64(len(members)) + totalPages, currentPage, err = PaginateMemberList(&members, getOptions) + return } -// paginateMemberList returns paginated results if meaningful options are provided, options should never be nil. +// PaginateMemberList returns paginated results if meaningful options are provided. Options should never be nil. // Paginated results are continuous only when there is no member change across multiple calls. -// Pagination is not processed if either page number or limit = 0, thus returns full member list. -// Returns an error for invalid options; returns empty list for page number beyond the total pages range. -func paginateMemberList(memberList *controlplane.ClusterGroupMembers, pageInfo *controlplane.PaginationGetOptions) error { +// Pagination is not enabled if either page number or limit = 0, in which the full member list is returned. +// An error is returned for invalid options, and an empty list is returned for a page number out of the pages range. +func PaginateMemberList(effectiveMembers *[]controlplane.GroupMember, pageInfo *controlplane.PaginationGetOptions) (int64, int64, error) { if pageInfo.Limit < 0 { - return errors.NewBadRequest(fmt.Sprintf("received invalid page limit %d for pagination", pageInfo.Limit)) + return 0, 0, errors.NewBadRequest(fmt.Sprintf("received invalid page limit %d for pagination", pageInfo.Limit)) } else if pageInfo.Page < 0 { - return errors.NewBadRequest(fmt.Sprintf("received invalid page number %d for pagination", pageInfo.Page)) + return 0, 0, errors.NewBadRequest(fmt.Sprintf("received invalid page number %d for pagination", pageInfo.Page)) } - if memberList.TotalMembers == 0 { - memberList.TotalPages, memberList.CurrentPage = 0, 0 - return nil + if len(*effectiveMembers) == 0 { + return 0, 0, nil } - // Sort members based on name of ee/pod to realize consistent pagination support. - sort.SliceStable(memberList.EffectiveMembers, func(i, j int) bool { - if memberList.EffectiveMembers[i].Pod != nil && memberList.EffectiveMembers[j].Pod != nil { - return memberList.EffectiveMembers[i].Pod.Name < memberList.EffectiveMembers[j].Pod.Name - } else if memberList.EffectiveMembers[i].ExternalEntity != nil && memberList.EffectiveMembers[j].ExternalEntity != nil { - return memberList.EffectiveMembers[i].ExternalEntity.Name < memberList.EffectiveMembers[j].ExternalEntity.Name + // Sort members based on EE/Pod names to realize consistent pagination results. + sort.SliceStable(*effectiveMembers, func(i, j int) bool { + if (*effectiveMembers)[i].Pod != nil && (*effectiveMembers)[j].Pod != nil { + return (*effectiveMembers)[i].Pod.Name < (*effectiveMembers)[j].Pod.Name + } else if (*effectiveMembers)[i].ExternalEntity != nil && (*effectiveMembers)[j].ExternalEntity != nil { + return (*effectiveMembers)[i].ExternalEntity.Name < (*effectiveMembers)[j].ExternalEntity.Name } else { return true } }) if pageInfo.Limit == 0 { - memberList.TotalPages, memberList.CurrentPage = 1, 1 - return nil + return 1, 1, nil } - totalPages := (int64(len(memberList.EffectiveMembers)) + pageInfo.Limit - 1) / pageInfo.Limit - memberList.TotalPages = totalPages - memberList.CurrentPage = pageInfo.Page + totalPages := (int64(len(*effectiveMembers)) + pageInfo.Limit - 1) / pageInfo.Limit if totalPages >= pageInfo.Page && pageInfo.Page > 0 { beginMember := (pageInfo.Page - 1) * pageInfo.Limit - memberList.EffectiveMembers = memberList.EffectiveMembers[beginMember:] - if pageInfo.Limit < int64(len(memberList.EffectiveMembers)) { - memberList.EffectiveMembers = memberList.EffectiveMembers[:pageInfo.Limit] + *effectiveMembers = (*effectiveMembers)[beginMember:] + if pageInfo.Limit < int64(len(*effectiveMembers)) { + *effectiveMembers = (*effectiveMembers)[:pageInfo.Limit] } } else if totalPages < pageInfo.Page { - // Returns empty memberList if page number exceeds total pages, to indicate end of list. - memberList.EffectiveMembers = memberList.EffectiveMembers[:0] + // Returns an empty member list if the page number exceeds total pages, to indicate end of list. + *effectiveMembers = (*effectiveMembers)[:0] } - return nil + return totalPages, pageInfo.Page, nil } diff --git a/pkg/apiserver/registry/networkpolicy/clustergroupmember/rest_test.go b/pkg/apiserver/registry/networkpolicy/clustergroupmember/rest_test.go index 39358ff4d45..f0edde36804 100644 --- a/pkg/apiserver/registry/networkpolicy/clustergroupmember/rest_test.go +++ b/pkg/apiserver/registry/networkpolicy/clustergroupmember/rest_test.go @@ -69,7 +69,31 @@ func getTestMembersBasic() map[string]controlplane.GroupMemberSet { } } -func getTestMembersPagination() map[string]controlplane.GroupMemberSet { +func getTestMembersPagination(ifExternalEntity bool) map[string]controlplane.GroupMemberSet { + if ifExternalEntity { + return map[string]controlplane.GroupMemberSet{ + "cgB": { + "memberKey1": &controlplane.GroupMember{ + ExternalEntity: &controlplane.ExternalEntityReference{ + Name: "ee2", + Namespace: "ns1", + }, + IPs: []controlplane.IPAddress{ + []byte{127, 10, 0, 1}, + }, + }, + "memberKey2": &controlplane.GroupMember{ + ExternalEntity: &controlplane.ExternalEntityReference{ + Name: "ee1", + Namespace: "ns1", + }, + IPs: []controlplane.IPAddress{ + []byte{127, 10, 0, 1}, + }, + }, + }, + } + } return map[string]controlplane.GroupMemberSet{ "cgA": { "memberKey1": &controlplane.GroupMember{ @@ -224,6 +248,7 @@ func TestRESTGetPagination(t *testing.T) { tests := []struct { name string groupName string + ifExternalEntity bool paginationOptions runtime.Object expectedObj runtime.Object expectedErr bool @@ -287,6 +312,32 @@ func TestRESTGetPagination(t *testing.T) { }, expectedErr: false, }, + { + name: "page1/2-group-member-pagination", + groupName: "cgB", + ifExternalEntity: true, + paginationOptions: &controlplane.PaginationGetOptions{Page: 2, Limit: 1}, + expectedObj: &controlplane.ClusterGroupMembers{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cgB", + }, + EffectiveMembers: []controlplane.GroupMember{ + { + ExternalEntity: &controlplane.ExternalEntityReference{ + Name: "ee2", + Namespace: "ns1", + }, + IPs: []controlplane.IPAddress{ + []byte{127, 10, 0, 1}, + }, + }, + }, + TotalMembers: 2, + TotalPages: 2, + CurrentPage: 2, + }, + expectedErr: false, + }, { name: "exceed-page-group-member-pagination", groupName: "cgA", @@ -358,8 +409,8 @@ func TestRESTGetPagination(t *testing.T) { expectedErr: true, }, } - rest := NewREST(fakeQuerier{members: getTestMembersPagination()}) for _, tt := range tests { + rest := NewREST(fakeQuerier{members: getTestMembersPagination(tt.ifExternalEntity)}) actualGroupList, err := rest.Get(request.NewDefaultContext(), tt.groupName, tt.paginationOptions) if tt.expectedErr { require.Error(t, err) diff --git a/pkg/apiserver/registry/networkpolicy/groupmember/rest.go b/pkg/apiserver/registry/networkpolicy/groupmember/rest.go new file mode 100644 index 00000000000..8e2c3d53447 --- /dev/null +++ b/pkg/apiserver/registry/networkpolicy/groupmember/rest.go @@ -0,0 +1,73 @@ +// Copyright 2023 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package groupmember + +import ( + "context" + + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/registry/rest" + + "antrea.io/antrea/pkg/apis/controlplane" + "antrea.io/antrea/pkg/apiserver/registry/networkpolicy/clustergroupmember" + "antrea.io/antrea/pkg/util/k8s" +) + +type REST struct { + querier clustergroupmember.GroupMembershipQuerier +} + +var ( + _ rest.Storage = &REST{} + _ rest.Scoper = &REST{} + _ rest.GetterWithOptions = &REST{} +) + +// NewREST returns a REST object that will work against API services. +func NewREST(querier clustergroupmember.GroupMembershipQuerier) *REST { + return &REST{querier} +} + +func (r *REST) New() runtime.Object { + return &controlplane.GroupMembers{} +} + +func (r *REST) Destroy() { +} + +func (r *REST) Get(ctx context.Context, name string, options runtime.Object) (runtime.Object, error) { + ns, ok := request.NamespaceFrom(ctx) + if !ok || len(ns) == 0 { + return nil, errors.NewBadRequest("Namespace parameter required.") + } + groupName := k8s.NamespacedName(ns, name) + var err error + memberList := &controlplane.GroupMembers{} + memberList.Namespace = ns + memberList.Name = name + memberList.EffectiveMembers, memberList.EffectiveIPBlocks, memberList.TotalMembers, memberList.TotalPages, memberList.CurrentPage, err = clustergroupmember.GetPaginatedMembers(r.querier, groupName, options) + return memberList, err +} + +// NewGetOptions returns the default options for Get, so options object is never nil. +func (r *REST) NewGetOptions() (runtime.Object, bool, string) { + return &controlplane.PaginationGetOptions{}, false, "" +} + +func (r *REST) NamespaceScoped() bool { + return true +} diff --git a/pkg/apiserver/registry/networkpolicy/groupmember/rest_test.go b/pkg/apiserver/registry/networkpolicy/groupmember/rest_test.go new file mode 100644 index 00000000000..e3a086471aa --- /dev/null +++ b/pkg/apiserver/registry/networkpolicy/groupmember/rest_test.go @@ -0,0 +1,211 @@ +// Copyright 2023 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package groupmember + +import ( + "net" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/endpoints/request" + + "antrea.io/antrea/pkg/apis/controlplane" +) + +type fakeQuerier struct { + members map[string]controlplane.GroupMemberSet + ipMembers map[string][]controlplane.IPBlock +} + +func (q fakeQuerier) GetGroupMembers(uid string) (controlplane.GroupMemberSet, []controlplane.IPBlock, error) { + if ipMemberList, ok := q.ipMembers[uid]; ok { + return nil, ipMemberList, nil + } + if memberList, ok := q.members[uid]; ok { + return memberList, nil, nil + } + return nil, nil, nil +} + +func getTestMembers() map[string]controlplane.GroupMemberSet { + return map[string]controlplane.GroupMemberSet{ + "default/ngA": { + "memberKey1": &controlplane.GroupMember{ + Pod: &controlplane.PodReference{ + Name: "pod1", + Namespace: "ns1", + }, + IPs: []controlplane.IPAddress{ + []byte{127, 10, 0, 1}, + }, + }, + }, + "default/ngB": { + "memberKey2": &controlplane.GroupMember{ + ExternalEntity: &controlplane.ExternalEntityReference{ + Name: "ee2", + Namespace: "ns1", + }, + IPs: []controlplane.IPAddress{ + []byte{127, 10, 0, 2}, + }, + }, + }, + } +} + +func getTestIPMembers() map[string][]controlplane.IPBlock { + testCIDR := controlplane.IPNet{ + IP: controlplane.IPAddress(net.ParseIP("10.0.0.1")), + PrefixLength: int32(24), + } + ipb := []controlplane.IPBlock{{CIDR: testCIDR}} + return map[string][]controlplane.IPBlock{ + "ns2/ngIPBlock": ipb, + } +} + +func TestREST(t *testing.T) { + r := NewREST(nil) + assert.Equal(t, &controlplane.GroupMembers{}, r.New()) + assert.True(t, r.NamespaceScoped()) +} + +func TestRESTGet(t *testing.T) { + tests := []struct { + name string + groupName string + namespace string + expectedObj runtime.Object + expectedErr bool + }{ + { + name: "single-pod-group-member", + groupName: "ngA", + namespace: "default", + expectedObj: &controlplane.GroupMembers{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ngA", + Namespace: "default", + }, + EffectiveMembers: []controlplane.GroupMember{ + { + Pod: &controlplane.PodReference{ + Name: "pod1", + Namespace: "ns1", + }, + IPs: []controlplane.IPAddress{ + []byte{127, 10, 0, 1}, + }, + }, + }, + TotalMembers: 1, + TotalPages: 1, + CurrentPage: 1, + }, + expectedErr: false, + }, + { + name: "single-ee-group-member", + groupName: "ngB", + namespace: "default", + expectedObj: &controlplane.GroupMembers{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ngB", + Namespace: "default", + }, + EffectiveMembers: []controlplane.GroupMember{ + { + ExternalEntity: &controlplane.ExternalEntityReference{ + Name: "ee2", + Namespace: "ns1", + }, + IPs: []controlplane.IPAddress{ + []byte{127, 10, 0, 2}, + }, + }, + }, + TotalMembers: 1, + TotalPages: 1, + CurrentPage: 1, + }, + expectedErr: false, + }, + { + name: "no-group-member", + groupName: "ngC", + namespace: "default", + expectedObj: &controlplane.GroupMembers{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ngC", + Namespace: "default", + }, + TotalMembers: 0, + TotalPages: 0, + CurrentPage: 0, + }, + expectedErr: false, + }, + { + name: "no-group-member-in-namespace", + groupName: "ngA", + namespace: "test", + expectedObj: &controlplane.GroupMembers{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ngA", + Namespace: "test", + }, + TotalMembers: 0, + TotalPages: 0, + CurrentPage: 0, + }, + expectedErr: false, + }, + { + name: "ipBlock-ng", + groupName: "ngIPBlock", + namespace: "ns2", + expectedObj: &controlplane.GroupMembers{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ngIPBlock", + Namespace: "ns2", + }, + EffectiveIPBlocks: []controlplane.IPNet{ + { + IP: controlplane.IPAddress(net.ParseIP("10.0.0.1")), + PrefixLength: int32(24), + }, + }, + TotalMembers: 0, + TotalPages: 0, + CurrentPage: 0, + }, + expectedErr: false, + }, + } + rest := NewREST(fakeQuerier{members: getTestMembers(), ipMembers: getTestIPMembers()}) + for _, tt := range tests { + actualGroupList, err := rest.Get(request.WithNamespace(request.NewContext(), tt.namespace), tt.groupName, &controlplane.PaginationGetOptions{}) + if tt.expectedErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + assert.Equal(t, tt.expectedObj, actualGroupList) + } +} diff --git a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/controlplane_client.go b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/controlplane_client.go index 7bada10f68b..98c7b89f758 100644 --- a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/controlplane_client.go +++ b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/controlplane_client.go @@ -31,6 +31,7 @@ type ControlplaneV1beta2Interface interface { ClusterGroupMembersGetter EgressGroupsGetter GroupAssociationsGetter + GroupMembersGetter IPGroupAssociationsGetter NetworkPoliciesGetter NodeStatsSummariesGetter @@ -62,6 +63,10 @@ func (c *ControlplaneV1beta2Client) GroupAssociations(namespace string) GroupAss return newGroupAssociations(c, namespace) } +func (c *ControlplaneV1beta2Client) GroupMembers(namespace string) GroupMembersInterface { + return newGroupMembers(c, namespace) +} + func (c *ControlplaneV1beta2Client) IPGroupAssociations() IPGroupAssociationInterface { return newIPGroupAssociations(c) } diff --git a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_controlplane_client.go b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_controlplane_client.go index cc417cf9170..232d3b75f8a 100644 --- a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_controlplane_client.go +++ b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_controlplane_client.go @@ -46,6 +46,10 @@ func (c *FakeControlplaneV1beta2) GroupAssociations(namespace string) v1beta2.Gr return &FakeGroupAssociations{c, namespace} } +func (c *FakeControlplaneV1beta2) GroupMembers(namespace string) v1beta2.GroupMembersInterface { + return &FakeGroupMembers{c, namespace} +} + func (c *FakeControlplaneV1beta2) IPGroupAssociations() v1beta2.IPGroupAssociationInterface { return &FakeIPGroupAssociations{c} } diff --git a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_groupmembers.go b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_groupmembers.go new file mode 100644 index 00000000000..2805f704965 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_groupmembers.go @@ -0,0 +1,47 @@ +// Copyright 2023 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1beta2 "antrea.io/antrea/pkg/apis/controlplane/v1beta2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + schema "k8s.io/apimachinery/pkg/runtime/schema" + testing "k8s.io/client-go/testing" +) + +// FakeGroupMembers implements GroupMembersInterface +type FakeGroupMembers struct { + Fake *FakeControlplaneV1beta2 + ns string +} + +var groupmembersResource = schema.GroupVersionResource{Group: "controlplane.antrea.io", Version: "v1beta2", Resource: "groupmembers"} + +var groupmembersKind = schema.GroupVersionKind{Group: "controlplane.antrea.io", Version: "v1beta2", Kind: "GroupMembers"} + +// Get takes name of the groupMembers, and returns the corresponding groupMembers object, and an error if there is any. +func (c *FakeGroupMembers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.GroupMembers, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(groupmembersResource, c.ns, name), &v1beta2.GroupMembers{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta2.GroupMembers), err +} diff --git a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/generated_expansion.go b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/generated_expansion.go index ab56cd87d39..b8bde69a5e5 100644 --- a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/generated_expansion.go @@ -26,6 +26,8 @@ type EgressGroupExpansion interface{} type GroupAssociationExpansion interface{} +type GroupMembersExpansion interface{} + type IPGroupAssociationExpansion interface{} type NodeStatsSummaryExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/groupmembers.go b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/groupmembers.go new file mode 100644 index 00000000000..a76e57ec033 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/groupmembers.go @@ -0,0 +1,65 @@ +// Copyright 2023 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta2 + +import ( + "context" + + v1beta2 "antrea.io/antrea/pkg/apis/controlplane/v1beta2" + scheme "antrea.io/antrea/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + rest "k8s.io/client-go/rest" +) + +// GroupMembersGetter has a method to return a GroupMembersInterface. +// A group's client should implement this interface. +type GroupMembersGetter interface { + GroupMembers(namespace string) GroupMembersInterface +} + +// GroupMembersInterface has methods to work with GroupMembers resources. +type GroupMembersInterface interface { + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta2.GroupMembers, error) + GroupMembersExpansion +} + +// groupMembers implements GroupMembersInterface +type groupMembers struct { + client rest.Interface + ns string +} + +// newGroupMembers returns a GroupMembers +func newGroupMembers(c *ControlplaneV1beta2Client, namespace string) *groupMembers { + return &groupMembers{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the groupMembers, and returns the corresponding groupMembers object, and an error if there is any. +func (c *groupMembers) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.GroupMembers, err error) { + result = &v1beta2.GroupMembers{} + err = c.client.Get(). + Namespace(c.ns). + Resource("groupmembers"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} diff --git a/pkg/controller/networkpolicy/clustergroup.go b/pkg/controller/networkpolicy/clustergroup.go index 079065114c2..735b365c241 100644 --- a/pkg/controller/networkpolicy/clustergroup.go +++ b/pkg/controller/networkpolicy/clustergroup.go @@ -421,17 +421,17 @@ func (c *NetworkPolicyController) getParentGroups(grpName string) []antreatypes. return groups } -// GetGroupMembers returns the current members of a ClusterGroup. -// If the ClusterGroup is defined with IPBlocks, the returned members will be []controlplane.IPBlock. +// GetGroupMembers returns the current members of a ClusterGroup/Group. +// If the ClusterGroup/Group is defined with IPBlocks, the returned members will be []controlplane.IPBlock. // Otherwise, the returned members will be of type controlplane.GroupMemberSet. -func (c *NetworkPolicyController) GetGroupMembers(cgName string) (controlplane.GroupMemberSet, []controlplane.IPBlock, error) { - groupObj, found, _ := c.internalGroupStore.Get(cgName) +func (c *NetworkPolicyController) GetGroupMembers(name string) (controlplane.GroupMemberSet, []controlplane.IPBlock, error) { + groupObj, found, _ := c.internalGroupStore.Get(name) if found { group := groupObj.(*antreatypes.Group) member, ipb := c.getInternalGroupMembers(group) return member, ipb, nil } - return nil, nil, fmt.Errorf("no internal Group with name %s is found", cgName) + return nil, nil, fmt.Errorf("no internal Group with name %s is found", name) } func (c *NetworkPolicyController) GetAssociatedIPBlockGroups(ip net.IP) []antreatypes.Group { diff --git a/pkg/controller/networkpolicy/clustergroup_test.go b/pkg/controller/networkpolicy/clustergroup_test.go index e273c4adb65..e957d024318 100644 --- a/pkg/controller/networkpolicy/clustergroup_test.go +++ b/pkg/controller/networkpolicy/clustergroup_test.go @@ -879,7 +879,7 @@ func TestGetAssociatedGroups(t *testing.T) { } } -func TestGetGroupMembers(t *testing.T) { +func TestGetClusterGroupMembers(t *testing.T) { pod1MemberSet := controlplane.GroupMemberSet{} pod1MemberSet.Insert(podToGroupMember(testPods[0], true)) pod12MemberSet := controlplane.GroupMemberSet{} diff --git a/pkg/controller/networkpolicy/group.go b/pkg/controller/networkpolicy/group.go index 4fdb1345792..ab2486330a6 100644 --- a/pkg/controller/networkpolicy/group.go +++ b/pkg/controller/networkpolicy/group.go @@ -27,6 +27,7 @@ import ( "antrea.io/antrea/pkg/apis/controlplane" crdv1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1" antreatypes "antrea.io/antrea/pkg/controller/types" + "antrea.io/antrea/pkg/util/k8s" ) // addGroup is responsible for processing the ADD event of a Group resource. @@ -181,7 +182,7 @@ func (n *NetworkPolicyController) syncInternalNamespacedGroup(grp *antreatypes.G // 2. All its child groups are created and realized. if len(grp.ChildGroups) > 0 { for _, cgName := range grp.ChildGroups { - internalGroup, found, _ := n.internalGroupStore.Get(grp.SourceReference.Namespace + "/" + cgName) + internalGroup, found, _ := n.internalGroupStore.Get(k8s.NamespacedName(grp.SourceReference.Namespace, cgName)) if !found || internalGroup.(*antreatypes.Group).MembersComputed != v1.ConditionTrue { membersComputed = false break diff --git a/pkg/controller/networkpolicy/group_test.go b/pkg/controller/networkpolicy/group_test.go index c743d098d71..153266c48a0 100644 --- a/pkg/controller/networkpolicy/group_test.go +++ b/pkg/controller/networkpolicy/group_test.go @@ -26,6 +26,7 @@ import ( "antrea.io/antrea/pkg/apis/controlplane" crdv1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1" antreatypes "antrea.io/antrea/pkg/controller/types" + "antrea.io/antrea/pkg/util/k8s" ) func TestProcessGroup(t *testing.T) { @@ -536,3 +537,54 @@ func TestGetGroupSourceRef(t *testing.T) { }) } } + +func TestGetGroupMembers(t *testing.T) { + var namespacedGroups []antreatypes.Group + for _, group := range groups { + group.SourceReference.Namespace = "test-ns" + namespacedGroups = append(namespacedGroups, group) + } + pod1MemberSet := controlplane.GroupMemberSet{} + pod1MemberSet.Insert(podToGroupMember(testPods[0], true)) + pod12MemberSet := controlplane.GroupMemberSet{} + pod12MemberSet.Insert(podToGroupMember(testPods[0], true)) + pod12MemberSet.Insert(podToGroupMember(testPods[1], true)) + tests := []struct { + name string + group antreatypes.Group + expectedMembers controlplane.GroupMemberSet + }{ + { + "multiple-members", + namespacedGroups[1], + pod12MemberSet, + }, + { + "single-member", + namespacedGroups[0], + pod1MemberSet, + }, + { + "no-member", + namespacedGroups[2], + controlplane.GroupMemberSet{}, + }, + } + _, npc := newController(nil, nil) + for i := range testPods { + npc.groupingInterface.AddPod(testPods[i]) + } + for j := range externalEntities { + npc.groupingInterface.AddExternalEntity(externalEntities[j]) + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + npc.internalGroupStore.Create(&tt.group) + groupName := k8s.NamespacedName(tt.group.SourceReference.Namespace, tt.group.SourceReference.Name) + npc.groupingInterface.AddGroup(internalGroupType, groupName, tt.group.Selector) + members, _, err := npc.GetGroupMembers(groupName) + assert.Equal(t, nil, err) + assert.Equal(t, tt.expectedMembers, members) + }) + } +}