Skip to content

Commit

Permalink
Add Action to NetworkPolicy Evaluation response
Browse files Browse the repository at this point in the history
As necessary for networkpolicyevaluation consumption, this PR
adds the Action field to the above antctl command response.

Signed-off-by: Qiyue Yao <[email protected]>
  • Loading branch information
qiyueyao committed Mar 18, 2024
1 parent bc54253 commit a317d3a
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 33 deletions.
3 changes: 1 addition & 2 deletions pkg/antctl/output/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"io"
"reflect"
"sort"
"strconv"
"strings"
"text/tabwriter"

Expand Down Expand Up @@ -322,7 +321,7 @@ func TableOutputForQueryEndpoint(obj interface{}, writer io.Writer) error {
toStringRep := func(effectiveRules []endpointserver.Rule) [][]string {
ruleStrings := make([][]string, 0)
for _, rule := range effectiveRules {
ruleStrings = append(ruleStrings, []string{rule.PolicyRef.Name, rule.PolicyRef.Namespace, strconv.Itoa(rule.RuleIndex), string(rule.PolicyRef.UID)})
ruleStrings = append(ruleStrings, []string{rule.PolicyRef.Name, rule.PolicyRef.Namespace, fmt.Sprint(rule.RuleIndex), string(rule.PolicyRef.UID)})
}
return ruleStrings
}
Expand Down
9 changes: 7 additions & 2 deletions pkg/antctl/transform/networkpolicy/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,20 +180,25 @@ func EvaluationTransform(reader io.Reader, _ bool, _ map[string]string) (interfa
var _ common.TableOutput = new(EvaluationResponse)

func (r EvaluationResponse) GetTableHeader() []string {
return []string{"NAME", "NAMESPACE", "POLICY-TYPE", "RULE-INDEX", "DIRECTION"}
return []string{"NAME", "NAMESPACE", "POLICY-TYPE", "RULE-INDEX", "DIRECTION", "ACTION"}
}

func (r EvaluationResponse) GetTableRow(_ int) []string {
if r.NetworkPolicyEvaluation != nil && r.Response != nil {
action := ""
if r.Response.Rule.Action != nil {
action = string(*r.Response.Rule.Action)
}
return []string{
r.Response.NetworkPolicy.Name,
r.Response.NetworkPolicy.Namespace,
string(r.Response.NetworkPolicy.Type),
common.Int32ToString(r.Response.RuleIndex),
string(r.Response.Rule.Direction),
action,
}
}
return make([]string, 5)
return make([]string, len(r.GetTableHeader()))
}

func (r EvaluationResponse) SortRows() bool {
Expand Down
69 changes: 58 additions & 11 deletions pkg/antctl/transform/networkpolicy/response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package networkpolicy

import (
"fmt"
"math"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -23,6 +25,7 @@ import (
"k8s.io/utils/pointer"

cpv1beta "antrea.io/antrea/pkg/apis/controlplane/v1beta2"
crdv1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1"
)

func TestListTransform(t *testing.T) {
Expand Down Expand Up @@ -176,17 +179,61 @@ func TestListTransform(t *testing.T) {

func TestEvaluationResponseTransform(t *testing.T) {
test := EvaluationResponse{&cpv1beta.NetworkPolicyEvaluation{}}
assert.Equal(t, []string{"NAME", "NAMESPACE", "POLICY-TYPE", "RULE-INDEX", "DIRECTION"}, test.GetTableHeader())
assert.Equal(t, []string{"NAME", "NAMESPACE", "POLICY-TYPE", "RULE-INDEX", "DIRECTION", "ACTION"}, test.GetTableHeader())
assert.False(t, test.SortRows())
assert.Equal(t, []string{"", "", "", "", ""}, test.GetTableRow(32))
test.Response = &cpv1beta.NetworkPolicyEvaluationResponse{
NetworkPolicy: cpv1beta.NetworkPolicyReference{
Type: cpv1beta.K8sNetworkPolicy,
Namespace: "ns",
Name: "testName",
},
RuleIndex: 10,
Rule: cpv1beta.RuleRef{Direction: cpv1beta.DirectionIn},
assert.Equal(t, []string{"", "", "", "", "", ""}, test.GetTableRow(32))
testDropAction, testIsolationAction := crdv1beta1.RuleActionDrop, crdv1beta1.RuleActionIsolation

tests := []struct {
name string
testResponse *cpv1beta.NetworkPolicyEvaluationResponse
expectedOutput []string
}{
{
name: "k8s rule",
testResponse: &cpv1beta.NetworkPolicyEvaluationResponse{
NetworkPolicy: cpv1beta.NetworkPolicyReference{
Type: cpv1beta.K8sNetworkPolicy,
Namespace: "ns",
Name: "testK8s",
},
RuleIndex: 10,
Rule: cpv1beta.RuleRef{Direction: cpv1beta.DirectionIn},
},
expectedOutput: []string{"testK8s", "ns", "K8sNetworkPolicy", "10", "In", ""},
},
{
name: "anp rule",
testResponse: &cpv1beta.NetworkPolicyEvaluationResponse{
NetworkPolicy: cpv1beta.NetworkPolicyReference{
Type: cpv1beta.AntreaNetworkPolicy,
Namespace: "ns",
Name: "testANP",
},
RuleIndex: 10,
Rule: cpv1beta.RuleRef{Direction: cpv1beta.DirectionIn, Action: &testDropAction},
},
expectedOutput: []string{"testANP", "ns", "AntreaNetworkPolicy", "10", "In", "Drop"},
},
{
name: "k8s default isolation",
testResponse: &cpv1beta.NetworkPolicyEvaluationResponse{
NetworkPolicy: cpv1beta.NetworkPolicyReference{
Type: cpv1beta.K8sNetworkPolicy,
Namespace: "ns",
Name: "testK8s",
},
RuleIndex: math.MaxInt32,
Rule: cpv1beta.RuleRef{Direction: cpv1beta.DirectionIn, Action: &testIsolationAction},
},
expectedOutput: []string{"testK8s", "ns", "K8sNetworkPolicy", fmt.Sprint(math.MaxInt32), "In", "Isolation"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
test.Response = tt.testResponse
assert.Equal(t, tt.expectedOutput, test.GetTableRow(32))
})
}
assert.Equal(t, []string{"testName", "ns", "K8sNetworkPolicy", "10", "In"}, test.GetTableRow(32))
}
3 changes: 3 additions & 0 deletions pkg/apis/crd/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,9 @@ const (
// RuleActionReject indicates that the traffic matching the rule must be rejected and the
// client will receive a response.
RuleActionReject RuleAction = "Reject"
// RuleActionIsolation indicates that the traffic matching the rule should be
// affected by Kubernetes NetworkPolicy default isolation.
RuleActionIsolation RuleAction = "Isolation"

IGMPQuery int32 = 0x11
IGMPReportV1 int32 = 0x12
Expand Down
2 changes: 1 addition & 1 deletion pkg/apiserver/handlers/endpoint/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type EndpointQueryResponse struct {
type Rule struct {
PolicyRef v1beta2.NetworkPolicyReference `json:"policyref,omitempty"`
Direction v1beta2.Direction `json:"direction,omitempty"`
RuleIndex int `json:"ruleindex,omitempty"`
RuleIndex int32 `json:"ruleindex,omitempty"`
}

type Endpoint struct {
Expand Down
11 changes: 6 additions & 5 deletions pkg/controller/networkpolicy/endpoint_querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func (eq *EndpointQuerierImpl) QueryNetworkPolicyRules(namespace, podName string
return nil, err
}
for _, policy := range policies {
egressIndex, ingressIndex := 0, 0
egressIndex, ingressIndex := int32(0), int32(0)
for _, rule := range policy.(*antreatypes.NetworkPolicy).Rules {
for _, addressGroupTrial := range rule.To.AddressGroups {
if addressGroupTrial == string(addressGroup.(*antreatypes.AddressGroup).UID) {
Expand Down Expand Up @@ -185,17 +185,18 @@ func (eq *EndpointQuerierImpl) QueryNetworkPolicyRules(namespace, podName string
func processEndpointAppliedRules(appliedPolicies []*antreatypes.NetworkPolicy, isSourceEndpoint bool) (sets.Set[types.UID], []*antreatypes.RuleInfo) {
policyUIDs := sets.New[types.UID]()
isolationRules := make([]*antreatypes.RuleInfo, 0)
isolationAction := crdv1beta1.RuleActionIsolation
for _, internalPolicy := range appliedPolicies {
policyUIDs.Insert(internalPolicy.SourceRef.UID)
if internalPolicy.SourceRef.Type == controlplane.K8sNetworkPolicy {
// check if the Kubernetes NetworkPolicy creates ingress or egress isolationRules
for _, rule := range internalPolicy.Rules {
if rule.Direction == controlplane.DirectionIn && !isSourceEndpoint {
isolationRules = append(isolationRules, &antreatypes.RuleInfo{Policy: internalPolicy, Index: math.MaxInt,
Rule: &controlplane.NetworkPolicyRule{Direction: rule.Direction, Name: rule.Name, Action: rule.Action}})
isolationRules = append(isolationRules, &antreatypes.RuleInfo{Policy: internalPolicy, Index: math.MaxInt32,
Rule: &controlplane.NetworkPolicyRule{Direction: rule.Direction, Name: rule.Name, Action: &isolationAction}})
} else if rule.Direction == controlplane.DirectionOut && isSourceEndpoint {
isolationRules = append(isolationRules, &antreatypes.RuleInfo{Policy: internalPolicy, Index: math.MaxInt,
Rule: &controlplane.NetworkPolicyRule{Direction: rule.Direction, Name: rule.Name, Action: rule.Action}})
isolationRules = append(isolationRules, &antreatypes.RuleInfo{Policy: internalPolicy, Index: math.MaxInt32,
Rule: &controlplane.NetworkPolicyRule{Direction: rule.Direction, Name: rule.Name, Action: &isolationAction}})
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions pkg/controller/networkpolicy/endpoint_querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package networkpolicy

import (
"fmt"
"math"
"testing"
"time"

Expand Down Expand Up @@ -394,7 +395,7 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) {
for i := 0; i < len(policy.Rules); i++ {
ruleInfoMatches[i] = &antreatypes.RuleInfo{
Policy: policy,
Index: i,
Index: int32(i),
Rule: &controlplane.NetworkPolicyRule{Direction: policy.Rules[i].Direction, Name: policy.Rules[i].Name, Action: policy.Rules[i].Action},
}
}
Expand Down Expand Up @@ -528,8 +529,8 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) {
},
expectedResult: &controlplane.NetworkPolicyEvaluationResponse{
NetworkPolicy: controlplane.NetworkPolicyReference{Type: controlplane.K8sNetworkPolicy, Namespace: namespace, Name: "Policy111", UID: uid1},
RuleIndex: -1,
Rule: controlplane.RuleRef{Direction: controlplane.DirectionOut, Name: "Policy111Rule0"},
RuleIndex: math.MaxInt32,
Rule: controlplane.RuleRef{Direction: controlplane.DirectionOut, Name: "Policy111Rule0", Action: &isolationAction},
},
},
{
Expand All @@ -541,8 +542,8 @@ func TestQueryNetworkPolicyEvaluation(t *testing.T) {
},
expectedResult: &controlplane.NetworkPolicyEvaluationResponse{
NetworkPolicy: controlplane.NetworkPolicyReference{Type: controlplane.K8sNetworkPolicy, Namespace: namespace, Name: "Policy222", UID: uid2},
RuleIndex: -1,
Rule: controlplane.RuleRef{Direction: controlplane.DirectionIn, Name: "Policy222Rule0"},
RuleIndex: math.MaxInt32,
Rule: controlplane.RuleRef{Direction: controlplane.DirectionIn, Name: "Policy222Rule0", Action: &isolationAction},
},
},
{
Expand Down
13 changes: 7 additions & 6 deletions pkg/controller/networkpolicy/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ import (
)

var (
query = crdv1beta1.IGMPQuery
report = crdv1beta1.IGMPReportV1
allowAction = crdv1beta1.RuleActionAllow
dropAction = crdv1beta1.RuleActionDrop
passAction = crdv1beta1.RuleActionPass
portNum80 = int32(80)
query = crdv1beta1.IGMPQuery
report = crdv1beta1.IGMPReportV1
allowAction = crdv1beta1.RuleActionAllow
dropAction = crdv1beta1.RuleActionDrop
passAction = crdv1beta1.RuleActionPass
isolationAction = crdv1beta1.RuleActionIsolation
portNum80 = int32(80)
)

func TestValidateAntreaClusterNetworkPolicy(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/types/networkpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (p *NetworkPolicy) GetAppliedToGroups() sets.Set[string] {
// corresponding ingress/egress rules, and the original rule info.
type RuleInfo struct {
Policy *NetworkPolicy
Index int
Index int32
Rule *controlplane.NetworkPolicyRule
}

Expand Down

0 comments on commit a317d3a

Please sign in to comment.