Skip to content
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

Support static ipBlock queries for clustergroupmembership #2577

Merged
merged 3 commits into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions pkg/apis/controlplane/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
package controlplane

import (
"fmt"
"net"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -81,11 +84,12 @@ type GroupMember struct {

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ClusterGroupMembers is a list of GroupMember objects 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
EffectiveMembers []GroupMember
EffectiveMembers []GroupMember
EffectiveIPBlocks []IPNet
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down Expand Up @@ -120,12 +124,20 @@ type AddressGroup struct {
// IPAddress describes a single IP address. Either an IPv4 or IPv6 address must be set.
type IPAddress []byte

func (ip IPAddress) String() string {
return net.IP(ip).String()
}

// IPNet describes an IP network.
type IPNet struct {
IP IPAddress
PrefixLength int32
}

func (ipn IPNet) String() string {
return fmt.Sprintf("%s/%d", ipn.IP.String(), ipn.PrefixLength)
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// AddressGroupPatch describes the incremental update of an AddressGroup.
Expand Down
293 changes: 177 additions & 116 deletions pkg/apis/controlplane/v1beta2/generated.pb.go

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion pkg/apis/controlplane/v1beta2/generated.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pkg/apis/controlplane/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ type GroupMember struct {
// +genclient:onlyVerbs=get
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ClusterGroupMembers is a list of GroupMember objects 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"`
EffectiveMembers []GroupMember `json:"effectiveMembers" protobuf:"bytes,2,rep,name=effectiveMembers"`
EffectiveIPBlocks []IPNet `json:"effectiveIPBlocks" protobuf:"bytes,3,rep,name=effectiveIPBlocks"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/controlplane/v1beta2/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions pkg/apis/controlplane/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions pkg/apiserver/openapi/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 17 additions & 8 deletions pkg/apiserver/registry/networkpolicy/clustergroupmember/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,33 @@ func NewREST(querier groupMembershipQuerier) *REST {
}

type groupMembershipQuerier interface {
GetGroupMembers(name string) (controlplane.GroupMemberSet, error)
GetGroupMembers(name string) (controlplane.GroupMemberSet, []controlplane.IPBlock, error)
}

func (r *REST) New() runtime.Object {
return &controlplane.ClusterGroupMembers{}
}

func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
members, err := r.querier.GetGroupMembers(name)
groupMembers, ipBlocks, err := r.querier.GetGroupMembers(name)
if err != nil {
return nil, errors.NewInternalError(err)
}
effectiveMembers := make([]controlplane.GroupMember, 0, len(members))
for _, member := range members {
effectiveMembers = append(effectiveMembers, *member)
}
memberList := &controlplane.ClusterGroupMembers{
EffectiveMembers: effectiveMembers,
memberList := &controlplane.ClusterGroupMembers{}
if len(ipBlocks) > 0 {
effectiveIPBlocks := 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)
}
memberList.EffectiveIPBlocks = effectiveIPBlocks
} else {
effectiveMembers := make([]controlplane.GroupMember, 0, len(groupMembers))
for _, member := range groupMembers {
effectiveMembers = append(effectiveMembers, *member)
}
memberList.EffectiveMembers = effectiveMembers
}
memberList.Name = name
return memberList, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package clustergroupmember

import (
"net"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -27,14 +28,18 @@ import (
)

type fakeQuerier struct {
members map[string]controlplane.GroupMemberSet
members map[string]controlplane.GroupMemberSet
ipMembers map[string][]controlplane.IPBlock
}

func (q fakeQuerier) GetGroupMembers(uid string) (controlplane.GroupMemberSet, error) {
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
return memberList, nil, nil
}
return controlplane.GroupMemberSet{}, nil
return nil, nil, nil
}

func TestRESTGet(t *testing.T) {
Expand Down Expand Up @@ -62,6 +67,14 @@ func TestRESTGet(t *testing.T) {
},
},
}
testCIDR := controlplane.IPNet{
IP: controlplane.IPAddress(net.ParseIP("10.0.0.1")),
PrefixLength: int32(24),
}
ipb := []controlplane.IPBlock{{CIDR: testCIDR}}
ipMembers := map[string][]controlplane.IPBlock{
"cgIPBlock": ipb,
}
tests := []struct {
name string
groupName string
Expand Down Expand Up @@ -121,8 +134,24 @@ func TestRESTGet(t *testing.T) {
},
expectedErr: false,
},
{
name: "ipBlock-cg",
groupName: "cgIPBlock",
expectedObj: &controlplane.ClusterGroupMembers{
ObjectMeta: metav1.ObjectMeta{
Name: "cgIPBlock",
},
EffectiveIPBlocks: []controlplane.IPNet{
{
IP: controlplane.IPAddress(net.ParseIP("10.0.0.1")),
PrefixLength: int32(24),
},
},
},
expectedErr: false,
},
}
rest := NewREST(fakeQuerier{members: members})
rest := NewREST(fakeQuerier{members: members, ipMembers: ipMembers})
for _, tt := range tests {
actualGroupList, err := rest.Get(request.NewDefaultContext(), tt.groupName, &metav1.GetOptions{})
if tt.expectedErr {
Expand Down
15 changes: 10 additions & 5 deletions pkg/controller/networkpolicy/clustergroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ func (c *NetworkPolicyController) updateClusterGroup(oldObj, curObj interface{})
ipBlocksUpdated := func() bool {
oldIPBs, newIPBs := sets.String{}, sets.String{}
for _, ipb := range oldGroup.IPBlocks {
oldIPBs.Insert(ipNetToCIDRStr(ipb.CIDR))
oldIPBs.Insert(ipb.CIDR.String())
}
for _, ipb := range newGroup.IPBlocks {
newIPBs.Insert(ipNetToCIDRStr(ipb.CIDR))
newIPBs.Insert(ipb.CIDR.String())
}
return oldIPBs.Equal(newIPBs)
}
Expand Down Expand Up @@ -427,11 +427,16 @@ func (c *NetworkPolicyController) getAssociatedGroupsByName(grpName string) []an
}

// GetGroupMembers returns the current members of a ClusterGroup.
func (c *NetworkPolicyController) GetGroupMembers(cgName string) (controlplane.GroupMemberSet, error) {
// If the ClusterGroup 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)
if found {
group := groupObj.(*antreatypes.Group)
return c.getClusterGroupMemberSet(group), nil
if len(group.IPBlocks) > 0 {
return nil, group.IPBlocks, nil
}
return c.getClusterGroupMemberSet(group), nil, nil
}
return controlplane.GroupMemberSet{}, fmt.Errorf("no internal Group with name %s is found", cgName)
return nil, nil, fmt.Errorf("no internal Group with name %s is found", cgName)
}
2 changes: 1 addition & 1 deletion pkg/controller/networkpolicy/clustergroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ func TestGetGroupMembers(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
npc.internalGroupStore.Create(&tt.group)
npc.groupingInterface.AddGroup(clusterGroupType, tt.group.Name, tt.group.Selector)
members, err := npc.GetGroupMembers(tt.group.Name)
members, _, err := npc.GetGroupMembers(tt.group.Name)
assert.Equal(t, nil, err)
assert.Equal(t, tt.expectedMembers, members)
})
Expand Down
5 changes: 0 additions & 5 deletions pkg/controller/networkpolicy/networkpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1425,11 +1425,6 @@ func cidrStrToIPNet(cidr string) (*controlplane.IPNet, error) {
return ipNet, nil
}

// ipNetToCIDRStr returns the CIDR notation of a controlplane.IPNet.
func ipNetToCIDRStr(ipNet controlplane.IPNet) string {
return net.IP(ipNet.IP).String() + "/" + strconv.Itoa(int(ipNet.PrefixLength))
}

// internalNetworkPolicyKeyFunc knows how to generate the key for an internal NetworkPolicy based on the object metadata
// of the corresponding original NetworkPolicy resource (also referred to as the "source").
// The key must be unique across K8s NetworkPolicies, Antrea NetworkPolicies, and Antrea ClusterNetworkPolicies.
Expand Down
Loading