Skip to content

Commit

Permalink
Address comments and add more test cases
Browse files Browse the repository at this point in the history
Signed-off-by: Wenqi Qiu <wenqiq@vmware.com>
  • Loading branch information
wenqiq committed Mar 20, 2022
1 parent 02629f9 commit 8e9146f
Show file tree
Hide file tree
Showing 155 changed files with 1,390 additions and 399 deletions.
19 changes: 13 additions & 6 deletions docs/antrea-network-policy.md
Expand Up @@ -547,8 +547,8 @@ specifies both namespaceSelector and podSelector selects particular Pods within
particular Namespaces.

**nodeSelector**: This selects particular Nodes in cluster. The selected Node's
IPs will set as "sources" if `nodeSelector` set in `ingress` section, or as
"destinations" if set in `egress` section.
IPs will be set as "sources" if `nodeSelector` set in `ingress` section, or as
"destinations" if is set in the `egress` section.

**namespaces**: A `namespaces` field allows users to perform advanced matching on
Namespace objects which cannot be done via label selectors. Currently, the
Expand Down Expand Up @@ -1109,10 +1109,17 @@ spec:

## Node Selector

NodeSelector selects certain Nodes which match the label selector. It adds Node IPs to egress rules in `to` field
or ingress rules in `from` filed.
The following rule applies to Pods with label `app=antrea-test-app` and will `Drop` egress traffic to
Nodes which have the labels `node-role.kubernetes.io/control-plane`.
NodeSelector selects certain Nodes which match the label selector.
When used in the `to` field of an egress rule, it adds the Node IPs to the rule's destination address group;
when used in the `from` field of an ingress rule, it adds the Node IPs to the rule's source address group.

Notice that rule with a nodeSelector only restrict the traffic to/from default Node IPs in cluster,
and the default Node IPs include NodeIP(the IP addresses of nodeInterface),
gatewayIP(the IP addresses of Antrea gatewayInterface) and transportIP(the IP addresses of transportInterface) of each Node.
Traffic to/from other Node interfaces will be ignored.

For example, the following rule applies to Pods with label `app=antrea-test-app` and will `Drop` egress traffic to
Nodes on TCP port 6443 which have the labels `node-role.kubernetes.io/control-plane`.

```yaml
apiVersion: crd.antrea.io/v1alpha1
Expand Down
20 changes: 5 additions & 15 deletions pkg/agent/controller/noderoute/node_route_controller.go
Expand Up @@ -17,7 +17,6 @@ package noderoute
import (
"fmt"
"net"
"strings"
"time"

"github.com/containernetworking/plugins/pkg/ip"
Expand Down Expand Up @@ -765,21 +764,12 @@ func getNodeMAC(node *corev1.Node) (net.HardwareAddr, error) {
}

func (c *Controller) getNodeTransportAddrs(node *corev1.Node) (*utilip.DualStackIPs, error) {
var transportAddrs = new(utilip.DualStackIPs)
if c.networkConfig.TransportIface != "" || len(c.networkConfig.TransportIfaceCIDRs) > 0 {
transportAddrsStr := node.Annotations[types.NodeTransportAddressAnnotationKey]
if transportAddrsStr != "" {
for _, addr := range strings.Split(transportAddrsStr, ",") {
peerNodeAddr := net.ParseIP(addr)
if peerNodeAddr == nil {
return nil, fmt.Errorf("invalid annotation for transport-address on Node %s: %s", node.Name, transportAddrsStr)
}
if peerNodeAddr.To4() == nil {
transportAddrs.IPv6 = peerNodeAddr
} else {
transportAddrs.IPv4 = peerNodeAddr
}
}
transportAddrs, err := k8s.GetNodeAddrsFromAnnotations(node, types.NodeTransportAddressAnnotationKey)
if err != nil {
return nil, err
}
if transportAddrs != nil {
return transportAddrs, nil
}
klog.InfoS("Transport address is not found, using NodeIP instead", "node", node.Name)
Expand Down
33 changes: 30 additions & 3 deletions pkg/antctl/command_definition_test.go
Expand Up @@ -219,9 +219,36 @@ foo2
Pods: []common.GroupMember{},
},
},
expected: `NAME POD-IPS
GroupName1 10.0.0.3,127.0.0.1,127.0.0.2,127.0.0.3 + 2 more...
GroupName2 <NONE>
expected: `NAME POD-IPS NODE-IPS
GroupName1 10.0.0.3,127.0.0.1,127.0.0.2,127.0.0.3 + 2 more... <NONE>
GroupName2 <NONE> <NONE>
`,
},
{
name: "StructureData-AddressGroup-HasNode",
rawResponseData: []addressgroup.Response{
{
Name: "AddressGroupNameHasNode",
Nodes: []common.GroupMember{
{IP: "127.0.0.1"}, {IP: "192.168.0.1"}, {IP: "10.176.27.105"}, {IP: "127.0.0.3"},
},
},
{
Name: "AddressGroupNameHasNode1",
Pods: []common.GroupMember{
{IP: "127.0.0.1"}, {IP: "192.168.0.1"}, {IP: "127.0.0.2"},
{IP: "127.0.0.3"}, {IP: "10.0.0.3"}, {IP: "127.0.0.5"}, {IP: "127.0.0.6"},
},
},
{
Name: "AddressGroupNameHasNode2",
Pods: []common.GroupMember{},
},
},
expected: `NAME POD-IPS NODE-IPS
AddressGroupNameHasNode <NONE> 10.176.27.105,127.0.0.1,127.0.0.3,192.168.0.1
AddressGroupNameHasNode1 10.0.0.3,127.0.0.1,127.0.0.2,127.0.0.3 + 2 more... <NONE>
AddressGroupNameHasNode2 <NONE> <NONE>
`,
},
{
Expand Down
32 changes: 23 additions & 9 deletions pkg/antctl/transform/addressgroup/transform.go
Expand Up @@ -24,8 +24,9 @@ import (
)

type Response struct {
Name string `json:"name" yaml:"name"`
Pods []common.GroupMember `json:"pods,omitempty"`
Name string `json:"name" yaml:"name"`
Pods []common.GroupMember `json:"pods,omitempty"`
Nodes []common.GroupMember `json:"nodes,omitempty"`
}

func listTransform(l interface{}, opts map[string]string) (interface{}, error) {
Expand All @@ -41,11 +42,16 @@ func listTransform(l interface{}, opts map[string]string) (interface{}, error) {

func objectTransform(o interface{}, _ map[string]string) (interface{}, error) {
group := o.(*cpv1beta.AddressGroup)
var pods []common.GroupMember
for _, pod := range group.GroupMembers {
pods = append(pods, common.GroupMemberPodTransform(pod))
var pods, nodes []common.GroupMember
for _, member := range group.GroupMembers {
gm := common.GroupMemberPodOrNodeTransform(member)
if member.Node != nil {
nodes = append(nodes, gm)
continue
}
pods = append(pods, gm)
}
return Response{Name: group.Name, Pods: pods}, nil
return Response{Name: group.Name, Pods: pods, Nodes: nodes}, nil
}

func Transform(reader io.Reader, single bool, opts map[string]string) (interface{}, error) {
Expand All @@ -61,19 +67,27 @@ func Transform(reader io.Reader, single bool, opts map[string]string) (interface
var _ common.TableOutput = new(Response)

func (r Response) GetTableHeader() []string {
return []string{"NAME", "POD-IPS"}
return []string{"NAME", "POD-IPS", "NODE-IPS"}
}

func (r Response) GetPodNames(maxColumnLength int) string {
func (r Response) GetPodIPs(maxColumnLength int) string {
list := make([]string, len(r.Pods))
for i, pod := range r.Pods {
list[i] = pod.IP
}
return common.GenerateTableElementWithSummary(list, maxColumnLength)
}

func (r Response) GetNodeIPs(maxColumnLength int) string {
list := make([]string, len(r.Nodes))
for i, node := range r.Nodes {
list[i] = node.IP
}
return common.GenerateTableElementWithSummary(list, maxColumnLength)
}

func (r Response) GetTableRow(maxColumnLength int) []string {
return []string{r.Name, r.GetPodNames(maxColumnLength)}
return []string{r.Name, r.GetPodIPs(maxColumnLength), r.GetNodeIPs(maxColumnLength)}
}

func (r Response) SortRows() bool {
Expand Down
2 changes: 1 addition & 1 deletion pkg/antctl/transform/appliedtogroup/transform.go
Expand Up @@ -43,7 +43,7 @@ func objectTransform(o interface{}, _ map[string]string) (interface{}, error) {
group := o.(*cpv1beta.AppliedToGroup)
var pods []common.GroupMember
for _, pod := range group.GroupMembers {
pods = append(pods, common.GroupMemberPodTransform(pod))
pods = append(pods, common.GroupMemberPodOrNodeTransform(pod))
}
return Response{Name: group.GetName(), Pods: pods}, nil
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/antctl/transform/common/transform.go
Expand Up @@ -24,22 +24,23 @@ import (
)

type GroupMember struct {
Pod *cpv1beta.PodReference `json:"pod,omitempty"`
Pod *cpv1beta.PodReference `json:"pod,omitempty"`
Node *cpv1beta.NodeReference `json:"node,omitempty"`
// IP maintains the IPAddresses associated with the Pod.
IP string `json:"ip,omitempty"`
// Ports maintain the named port mapping of this Pod.
Ports []cpv1beta.NamedPort `json:"ports,omitempty"`
}

func GroupMemberPodTransform(member cpv1beta.GroupMember) GroupMember {
func GroupMemberPodOrNodeTransform(member cpv1beta.GroupMember) GroupMember {
var ipStr string
for i, ip := range member.IPs {
if i != 0 {
ipStr += ", "
}
ipStr += net.IP(ip).String()
}
return GroupMember{Pod: member.Pod, IP: ipStr, Ports: member.Ports}
return GroupMember{Pod: member.Pod, IP: ipStr, Ports: member.Ports, Node: member.Node}
}

type TableOutput interface {
Expand Down
10 changes: 9 additions & 1 deletion pkg/apis/controlplane/types.go
Expand Up @@ -44,6 +44,12 @@ type PodReference struct {
Namespace string
}

// NodeReference represents a Node Reference.
type NodeReference struct {
// The name of this Node.
Name string
}

// ServiceReference represents reference to a v1.Service.
type ServiceReference struct {
// The name of this Service.
Expand All @@ -70,12 +76,14 @@ type ExternalEntityReference struct {
Namespace string
}

// GroupMember represents an resource member to be populated in Groups.
// GroupMember represents a resource member to be populated in Groups.
type GroupMember struct {
// Pod maintains the reference to the Pod.
Pod *PodReference
// ExternalEntity maintains the reference to the ExternalEntity.
ExternalEntity *ExternalEntityReference
// Node maintains the reference to the Node.
Node *NodeReference
// IP is the IP address of the Endpoints associated with the GroupMember.
IPs []IPAddress
// Ports is the list NamedPort of the GroupMember.
Expand Down

0 comments on commit 8e9146f

Please sign in to comment.