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 11, 2020
1 parent d1e0624 commit 3079f01
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 8 deletions.
67 changes: 62 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,68 @@ 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.Stable(sort.Reverse(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 {
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
switch nps.sortBy {
case sortByEffectivePriority:
if ti == tj {
if (pi == nil && pj == nil) || (pi != nil && pj != nil && *pi == *pj) {
return nps.networkPolicies[i].Name > nps.networkPolicies[j].Name
}
// If two NetworkPolicies are in the same tier and have different priorities
// (K8s NetworkPolicy will not apply since pi == pj == nil), the priorities
// of those NetworkPolicies must not be nil.
return *pi > *pj
}
return ti > tj
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 +120,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 +134,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
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 3079f01

Please sign in to comment.