-
Notifications
You must be signed in to change notification settings - Fork 373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Namespaced Group Membership API #5380
Conversation
0a79296
to
6203a0f
Compare
// 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An error is returned for invalid options, and an empty list is returned for a page number out of the pages range.
// +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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This struct is the same as ClusterGroupMembers. Do we need to redefine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And could not we reuse GroupMembers defined in pkg/apis/controlplane/v1beta2/types.go
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember controlplane/types.go
and v1beta2/types.go
where intentionally kept the same, is this outdated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Humm.. I do not know this. Let us see what @tnqn would recommend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For ClusterGroupMembers
and GroupMembers
, it's correct to redefine the struct even they are the same because every struct maps its own API, many generated code are based on the struct definition. Besides, it's a convention in K8s API, see https://github.com/kubernetes/kubernetes/blob/fb785f1f42183e26e2b9f042474391c4d58433bb/pkg/apis/rbac/types.go#L109-L120 and https://github.com/kubernetes/kubernetes/blob/fb785f1f42183e26e2b9f042474391c4d58433bb/pkg/apis/rbac/types.go#L174-L186
For controlplane/types.go
and v1beta2/types.go
, it's also correct to redefine the struct because the former is the internal representation of the data while the latter is the versioned one. The internal representation needs to be convertible with multiple versions so it may change along with the change of the API while the versioned one should remain compatible. For a new API, its internal struct and versioned struct is normally the same but they will diverge when the API evolves. The following docs has more informaiton:
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md
// +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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question - why we need to redefine a struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I redefined because on line 97 // +genclient:nonNamespaced
, ClusterGroupMembers API is non namespaced and GroupMembers API is namespaced, and the genclient
is auto generated. So I only generalized the pagination function not the Get(). Is there any suggestion to solve the problem? I'm not aware of, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we do:
type ClusterGroupMember GroupMember
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here? Then they are still not differentiated in terms of nonNamespaced
and namespaced
🤔
return nil, errors.NewInternalError(err) | ||
} | ||
// Retrieve options used for pagination. | ||
getOptions, ok := options.(*controlplane.PaginationGetOptions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use a shared type for Group and ClusterGroup, we can also share the Get() code with ClusterGroup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could extract the common code even when there are two different structs. It just needs a function like GetPaginatedMembers(querier groupMembershipQuerier, name string, options runtime.Object) (members []GroupMember, ipNets []IPNet, totalMembers, totalPages, currentPage int64)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall
// +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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For ClusterGroupMembers
and GroupMembers
, it's correct to redefine the struct even they are the same because every struct maps its own API, many generated code are based on the struct definition. Besides, it's a convention in K8s API, see https://github.com/kubernetes/kubernetes/blob/fb785f1f42183e26e2b9f042474391c4d58433bb/pkg/apis/rbac/types.go#L109-L120 and https://github.com/kubernetes/kubernetes/blob/fb785f1f42183e26e2b9f042474391c4d58433bb/pkg/apis/rbac/types.go#L174-L186
For controlplane/types.go
and v1beta2/types.go
, it's also correct to redefine the struct because the former is the internal representation of the data while the latter is the versioned one. The internal representation needs to be convertible with multiple versions so it may change along with the change of the API while the versioned one should remain compatible. For a new API, its internal struct and versioned struct is normally the same but they will diverge when the API evolves. The following docs has more informaiton:
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md
return nil, errors.NewInternalError(err) | ||
} | ||
// Retrieve options used for pagination. | ||
getOptions, ok := options.(*controlplane.PaginationGetOptions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could extract the common code even when there are two different structs. It just needs a function like GetPaginatedMembers(querier groupMembershipQuerier, name string, options runtime.Object) (members []GroupMember, ipNets []IPNet, totalMembers, totalPages, currentPage int64)
} | ||
|
||
type groupMembershipQuerier interface { | ||
GetGroupMembersByNamespace(name, namespace string) (controlplane.GroupMemberSet, []controlplane.IPBlock, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel the "ByNamespace" is a bit misleading. Although making it more accurate like ByNamespacedName could fix it, I wonder if we could just merge the two arguments and just use GetGroupMembers
given the callee doesn't need to separate it anyway, we could comment that the method accepts both ClusterGroup name and Group name.
Or we could rename existing GetGroupMembers to GetClusterGroupMembers which takes ClusterGroup name and add GetGroupMembers which takes Group Namespace and Name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, generalized GroupMembershipQuerier
and the common codes.
2f4e2a8
to
064b669
Compare
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it need to be public?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, updated.
Currently Antrea supports ClusterGroup and namespaced Group CRD, but only provides API for ClusterGroup membership. This solution adds membership API for namespaced Group at namespacedgroupmembers.controlplane.antrea.io. The group association API is still available for both ClusterGroup and namespaced Group. Fixes antrea-io#5269 Signed-off-by: Qiyue Yao <yaoq@vmware.com>
/test-all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@jianjuns any other comments? Do we need a pre-release like 1.14.0-alpha.0 for this API? |
LGTM |
Adds membership API for namespaced Group at
groupmembers.controlplane.antrea.io
. The group association API is still available for both ClusterGroup and namespaced Group.Fixes #5269