Skip to content

Commit

Permalink
Add sort-by effectivePriority for antctl get networkpolicy
Browse files Browse the repository at this point in the history
  • Loading branch information
Dyanngg committed Nov 17, 2020
1 parent 55e1fc2 commit 9849143
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 11 deletions.
64 changes: 59 additions & 5 deletions pkg/agent/apiserver/handlers/networkpolicy/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"net/http"
"net/url"
"sort"
"strings"

agentquerier "github.com/vmware-tanzu/antrea/pkg/agent/querier"
Expand All @@ -30,7 +31,7 @@ import (
// to query network policy rules in current agent.
func HandleFunc(aq agentquerier.AgentQuerier) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
npFilter, err := newFilterFromURLQuery(r.URL.Query())
npFilter, err := parseURLQuery(r.URL.Query())
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
Expand All @@ -48,15 +49,65 @@ func HandleFunc(aq agentquerier.AgentQuerier) http.HandlerFunc {
} else {
nps = npq.GetNetworkPolicies(npFilter)
}

obj = cpv1beta.NetworkPolicyList{Items: nps}
npSorter := &NPSorter{
networkPolicies: nps,
sortBy: r.URL.Query().Get("sort-by"),
}
sort.Sort(npSorter)
obj = cpv1beta.NetworkPolicyList{Items: npSorter.networkPolicies}

if err := json.NewEncoder(w).Encode(obj); err != nil {
http.Error(w, "Failed to encode response: "+err.Error(), http.StatusInternalServerError)
}
}
}

var (
sortByEffectivePriority = "effectivePriority"
// TODO: this is a hack, but works for now. 251 is a tierPriority value in
// between the application tier and the baseline tier, which can be used
// to sort policies by tier.
effectiveTierPriorityK8sNP = int32(251)
)

type NPSorter struct {
networkPolicies []cpv1beta.NetworkPolicy
sortBy string
}

func (nps *NPSorter) Len() int { return len(nps.networkPolicies) }
func (nps *NPSorter) Swap(i, j int) {
nps.networkPolicies[i], nps.networkPolicies[j] = nps.networkPolicies[j], nps.networkPolicies[i]
}
func (nps *NPSorter) Less(i, j int) bool {
switch nps.sortBy {
case sortByEffectivePriority:
var ti, tj int32
if nps.networkPolicies[i].TierPriority == nil {
ti = effectiveTierPriorityK8sNP
} else {
ti = *nps.networkPolicies[i].TierPriority
}
if nps.networkPolicies[j].TierPriority == nil {
tj = effectiveTierPriorityK8sNP
} else {
tj = *nps.networkPolicies[j].TierPriority
}
pi, pj := nps.networkPolicies[i].Priority, nps.networkPolicies[j].Priority
if ti != tj {
return ti < tj
}
if pi != nil && pj != nil && *pi != *pj {
return *pi < *pj
}
fallthrough
default:
// Do not need a tie-breaker here since NetworkPolicy names are set as UID
// of the source policy and will be unique.
return nps.networkPolicies[i].Name < nps.networkPolicies[j].Name
}
}

// From user shorthand input to cpv1beta1.NetworkPolicyType
var mapToNetworkPolicyType = map[string]cpv1beta.NetworkPolicyType{
"NP": cpv1beta.K8sNetworkPolicy,
Expand All @@ -66,7 +117,7 @@ var mapToNetworkPolicyType = map[string]cpv1beta.NetworkPolicyType{
}

// Create a Network Policy Filter from URL Query
func newFilterFromURLQuery(query url.Values) (*querier.NetworkPolicyQueryFilter, error) {
func parseURLQuery(query url.Values) (*querier.NetworkPolicyQueryFilter, error) {
namespace := query.Get("namespace")
pod := query.Get("pod")
if pod != "" && namespace == "" {
Expand All @@ -80,12 +131,15 @@ func newFilterFromURLQuery(query url.Values) (*querier.NetworkPolicyQueryFilter,
}

source := query.Get("source")

name := query.Get("name")
if name != "" && (source != "" || namespace != "" || pod != "" || strSourceType != "") {
return nil, fmt.Errorf("with a name, none of the other fields can be set")
}

sortBy := query.Get("sort-by")
if sortBy != "" && sortBy != sortByEffectivePriority {
return nil, fmt.Errorf("unsupported sort-by option. Supported value is %s", sortByEffectivePriority)
}
return &querier.NetworkPolicyQueryFilter{
Name: name,
SourceName: source,
Expand Down
7 changes: 7 additions & 0 deletions pkg/antctl/antctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ var CommandList = &commandList{
$ antctl get networkpolicy 6001549b-ba63-4752-8267-30f52b4332db
Get the list of all control plane NetworkPolicies
$ antctl get networkpolicy
Get the list of all control plane NetworkPolicies, sorted by effective priority (the order in which the policies are evaluated)
$ antctl get networkpolicy --sort-by=effectivePriority
Get the control plane NetworkPolicy with a specific source (supported by agent only)
$ antctl get networkpolicy -S allow-http -n ns1
Get the list of control plane NetworkPolicies whose source NetworkPolicies are in a Namespace (supported by agent only)
Expand Down Expand Up @@ -153,6 +155,11 @@ var CommandList = &commandList{
usage: "Get NetworkPolicies with specific type. Type means the type of its source network policy: K8sNP, ACNP, ANP",
shorthand: "T",
},
{
name: "sort-by",
usage: "Get NetworkPolicies by specific order. Current supported value is effectivePriority. If not specified, results are sorted by name by default.",
shorthand: "O",
},
},
outputType: multiple,
},
Expand Down
13 changes: 10 additions & 3 deletions pkg/antctl/command_definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ type Foobar struct {
Foo string `json:"foo"`
}

var (
AntreaPolicyTierPriority = int32(250)
AntreaPolicyPriority = float64(1.0)
)

func TestCommandList_tableOutputForGetCommands(t *testing.T) {
for _, tc := range []struct {
name string
Expand Down Expand Up @@ -172,6 +177,8 @@ foo2
ObjectMeta: metav1.ObjectMeta{
Name: "880db7e8-fc2a-4030-aefe-09afc5f341ad",
},
TierPriority: &AntreaPolicyTierPriority,
Priority: &AntreaPolicyPriority,
AppliedToGroups: []string{"32ef631b-6817-5a18-86eb-93f4abf0467c"},
Rules: []cpv1beta.NetworkPolicyRule{
{
Expand All @@ -192,9 +199,9 @@ foo2
},
},
},
expected: `NAME APPLIED-TO RULES SOURCE
6001549b-ba63-4752-8267-30f52b4332db 32ef631b-6817-5a18-86eb-93f4abf0467c + 1 more... 1 K8sNetworkPolicy:default/allow-all
880db7e8-fc2a-4030-aefe-09afc5f341ad 32ef631b-6817-5a18-86eb-93f4abf0467c 2 AntreaNetworkPolicy:default/allow-all
expected: `NAME APPLIED-TO RULES SOURCE TIER-PRIORITY PRIORITY
6001549b-ba63-4752-8267-30f52b4332db 32ef631b-6817-5a18-86eb-93f4abf0467c + 1 more... 1 K8sNetworkPolicy:default/allow-all <NONE> <NONE>
880db7e8-fc2a-4030-aefe-09afc5f341ad 32ef631b-6817-5a18-86eb-93f4abf0467c 2 AntreaNetworkPolicy:default/allow-all 250 1
`,
},
{
Expand Down
21 changes: 18 additions & 3 deletions pkg/antctl/transform/networkpolicy/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,31 @@ func Transform(reader io.Reader, single bool) (interface{}, error) {
)(reader, single)
}

func priorityToString(p interface{}) string {
if reflect.ValueOf(p).IsNil() {
return ""
} else if pInt32, ok := p.(*int32); ok {
return strconv.Itoa(int(*pInt32))
} else {
pFloat64, _ := p.(*float64)
return strconv.FormatFloat(*pFloat64, 'f', -1, 64)
}
}

var _ common.TableOutput = new(Response)

func (r Response) GetTableHeader() []string {
return []string{"NAME", "APPLIED-TO", "RULES", "SOURCE"}
return []string{"NAME", "APPLIED-TO", "RULES", "SOURCE", "TIER-PRIORITY", "PRIORITY"}
}

func (r Response) GetTableRow(maxColumnLength int) []string {
return []string{r.Name, common.GenerateTableElementWithSummary(r.AppliedToGroups, maxColumnLength), strconv.Itoa(len(r.Rules)), r.SourceRef.ToString()}
return []string{
r.Name, common.GenerateTableElementWithSummary(r.AppliedToGroups, maxColumnLength),
strconv.Itoa(len(r.Rules)), r.SourceRef.ToString(),
priorityToString(r.TierPriority), priorityToString(r.Priority),
}
}

func (r Response) SortRows() bool {
return true
return false
}

0 comments on commit 9849143

Please sign in to comment.