Skip to content

Commit

Permalink
Support static ipBlock queries for clustergroupmembership
Browse files Browse the repository at this point in the history
Signed-off-by: Yang Ding <dingyang@vmware.com>
  • Loading branch information
Dyanngg committed Aug 11, 2021
1 parent fe4457f commit 0b1d55f
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 150 deletions.
15 changes: 13 additions & 2 deletions pkg/apis/controlplane/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"net"
"strconv"

crdv1alpha1 "antrea.io/antrea/pkg/apis/crd/v1alpha1"
statsv1alpha1 "antrea.io/antrea/pkg/apis/stats/v1alpha1"
Expand Down Expand Up @@ -81,11 +83,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 +123,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 ipn.IP.String() + "/" + strconv.Itoa(int(ipn.PrefixLength))
}

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

// AddressGroupPatch describes the incremental update of an AddressGroup.
Expand Down
291 changes: 176 additions & 115 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) (interface{}, 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)
m, 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{}
switch members := m.(type) {
case controlplane.GroupMemberSet:
effectiveMembers := make([]controlplane.GroupMember, 0, len(members))
for _, member := range members {
effectiveMembers = append(effectiveMembers, *member)
}
memberList.EffectiveMembers = effectiveMembers
case []controlplane.IPBlock:
effectiveIPBlocks := make([]controlplane.IPNet, 0, len(members))
for _, member := range members {
// ClusterGroup ipBlock cannot have except slices
effectiveIPBlocks = append(effectiveIPBlocks, member.CIDR)
}
memberList.EffectiveIPBlocks = effectiveIPBlocks
}
memberList.Name = name
return memberList, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type fakeQuerier struct {
members map[string]controlplane.GroupMemberSet
}

func (q fakeQuerier) GetGroupMembers(uid string) (controlplane.GroupMemberSet, error) {
func (q fakeQuerier) GetGroupMembers(uid string) (interface{}, error) {
if memberList, ok := q.members[uid]; ok {
return memberList, nil
}
Expand Down
13 changes: 9 additions & 4 deletions pkg/controller/networkpolicy/clustergroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ func (n *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 (n *NetworkPolicyController) getAssociatedGroupsByName(grpName string) []an
}

// GetGroupMembers returns the current members of a ClusterGroup.
func (n *NetworkPolicyController) GetGroupMembers(cgName string) (controlplane.GroupMemberSet, error) {
// If the ClusterGroup is defined by IPBlocks, the returned members will be []controlplane.IPBlock.
// Otherwise, the returned members will be of type controlplane.GroupMemberSet.
func (n *NetworkPolicyController) GetGroupMembers(cgName string) (interface{}, error) {
groupObj, found, _ := n.internalGroupStore.Get(cgName)
if found {
group := groupObj.(*antreatypes.Group)
if len(group.IPBlocks) > 0 {
return group.IPBlocks, nil
}
return n.getClusterGroupMemberSet(group), nil
}
return controlplane.GroupMemberSet{}, fmt.Errorf("no internal Group with name %s is found", cgName)
return nil, fmt.Errorf("no internal Group with name %s is found", cgName)
}
5 changes: 0 additions & 5 deletions pkg/controller/networkpolicy/networkpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1426,11 +1426,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
29 changes: 19 additions & 10 deletions pkg/controller/networkpolicy/networkpolicy_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1434,7 +1434,8 @@ func TestAddPod(t *testing.T) {
updatedInAddrGroup := updatedInAddrGroupObj.(*antreatypes.AddressGroup)
updatedOutAddrGroupObj, _, _ := npc.addressGroupStore.Get(outGroupID)
updatedOutAddrGroup := updatedOutAddrGroupObj.(*antreatypes.AddressGroup)
groupMembers, _ := npc.GetGroupMembers(groupKey)
gm, _ := npc.GetGroupMembers(groupKey)
groupMembers, _ := gm.(controlplane.GroupMemberSet)
if tt.appGroupMatch {
assert.Len(t, podsAdded, 1, "expected Pod to match AppliedToGroup")
} else {
Expand Down Expand Up @@ -1532,7 +1533,8 @@ func TestDeletePod(t *testing.T) {
updatedAddrGroup := updatedAddrGroupObj.(*antreatypes.AddressGroup)
// Ensure Pod2 IP is removed from AddressGroup.
memberPod2 := &controlplane.GroupMember{IPs: []controlplane.IPAddress{ipStrToIPAddress(p2IP)}}
groupMembers, _ := npc.GetGroupMembers(groupKey)
gm, _ := npc.GetGroupMembers(groupKey)
groupMembers, _ := gm.(controlplane.GroupMemberSet)
assert.False(t, updatedAddrGroup.GroupMembers.Has(memberPod2))
assert.False(t, groupMembers.Has(memberPod2))
}
Expand Down Expand Up @@ -1676,7 +1678,8 @@ func TestAddNamespace(t *testing.T) {
updatedInAddrGroup := updatedInAddrGroupObj.(*antreatypes.AddressGroup)
updatedOutAddrGroupObj, _, _ := npc.addressGroupStore.Get(outGroupID)
updatedOutAddrGroup := updatedOutAddrGroupObj.(*antreatypes.AddressGroup)
groupMembers, _ := npc.GetGroupMembers(groupKey)
gm, _ := npc.GetGroupMembers(groupKey)
groupMembers, _ := gm.(controlplane.GroupMemberSet)
memberPod1 := &controlplane.GroupMember{
Pod: &controlplane.PodReference{Name: "p1", Namespace: "nsA"},
IPs: []controlplane.IPAddress{ipStrToIPAddress("1.2.3.4")},
Expand Down Expand Up @@ -1839,7 +1842,8 @@ func TestDeleteNamespace(t *testing.T) {
updatedInAddrGroup := updatedInAddrGroupObj.(*antreatypes.AddressGroup)
updatedOutAddrGroupObj, _, _ := npc.addressGroupStore.Get(outGroupID)
updatedOutAddrGroup := updatedOutAddrGroupObj.(*antreatypes.AddressGroup)
groupMembers, _ := npc.GetGroupMembers(groupKey)
gm, _ := npc.GetGroupMembers(groupKey)
groupMembers, _ := gm.(controlplane.GroupMemberSet)
memberPod1 := &controlplane.GroupMember{IPs: []controlplane.IPAddress{ipStrToIPAddress("1.1.1.1")}}
memberPod2 := &controlplane.GroupMember{IPs: []controlplane.IPAddress{ipStrToIPAddress("1.1.1.2")}}
if tt.inAddressGroupMatch {
Expand Down Expand Up @@ -1969,16 +1973,19 @@ func TestAddAndUpdateService(t *testing.T) {
},
IPs: []controlplane.IPAddress{ipStrToIPAddress("4.3.2.1")},
}
groupMembers1, _ := npc.GetGroupMembers(testCG1.Name)
gm1, _ := npc.GetGroupMembers(testCG1.Name)
groupMembers1, _ := gm1.(controlplane.GroupMemberSet)
assert.True(t, groupMembers1.Has(memberPod1))
assert.False(t, groupMembers1.Has(memberPod2))
groupMembers2, _ := npc.GetGroupMembers(testCG2.Name)
gm2, _ := npc.GetGroupMembers(testCG2.Name)
groupMembers2, _ := gm2.(controlplane.GroupMemberSet)
assert.False(t, groupMembers2.Has(memberPod1))
assert.False(t, groupMembers2.Has(memberPod2))
// Update svc-1 to select app test-2 instead
npc.serviceStore.Update(testSvc1Updated)
npc.syncInternalGroup(testCG1.Name)
groupMembers1Updated, _ := npc.GetGroupMembers(testCG1.Name)
gmu, _ := npc.GetGroupMembers(testCG1.Name)
groupMembers1Updated, _ := gmu.(controlplane.GroupMemberSet)
assert.False(t, groupMembers1Updated.Has(memberPod1))
assert.True(t, groupMembers1Updated.Has(memberPod2))
}
Expand Down Expand Up @@ -2036,12 +2043,14 @@ func TestDeleteService(t *testing.T) {
},
IPs: []controlplane.IPAddress{ipStrToIPAddress("1.2.3.4")},
}
groupMembers, _ := npc.GetGroupMembers(testCG.Name)
gm, _ := npc.GetGroupMembers(testCG.Name)
groupMembers, _ := gm.(controlplane.GroupMemberSet)
assert.True(t, groupMembers.Has(memberPod))
// Make sure that after Service deletion, the Pod member is removed from Group.
npc.serviceStore.Delete(testSvc)
npc.syncInternalGroup(testCG.Name)
groupMembersUpdated, _ := npc.GetGroupMembers(testCG.Name)
gmu, _ := npc.GetGroupMembers(testCG.Name)
groupMembersUpdated, _ := gmu.(controlplane.GroupMemberSet)
assert.False(t, groupMembersUpdated.Has(memberPod))
}

Expand Down Expand Up @@ -2940,7 +2949,7 @@ func TestIPNetToCIDRStr(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expC, ipNetToCIDRStr(tt.inC))
assert.Equal(t, tt.expC, tt.inC.String())
})
}
}
Expand Down

0 comments on commit 0b1d55f

Please sign in to comment.