-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
code updates - splitting formatters for convenience and group peers b…
…y ns for dot
- Loading branch information
1 parent
c9e1d07
commit 8235e39
Showing
6 changed files
with
206 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package connlist | ||
|
||
import ( | ||
"bytes" | ||
"encoding/csv" | ||
) | ||
|
||
// formatCSV: implements the connsFormatter interface for csv output format | ||
type formatCSV struct { | ||
} | ||
|
||
// returns a CSV string form of connections from list of Peer2PeerConnection objects | ||
func (cs formatCSV) writeOutput(conns []Peer2PeerConnection) (string, error) { | ||
// get an array of sorted conns items ([]singleConnFields) | ||
sortedConnItems := sortConnections(conns) | ||
var headerCSV = []string{"src", "dst", "conn"} | ||
|
||
// writing csv rows into a buffer | ||
buf := new(bytes.Buffer) | ||
writer := csv.NewWriter(buf) | ||
if err := writer.Write(headerCSV); err != nil { | ||
return "", err | ||
} | ||
for _, conn := range sortedConnItems { | ||
row := []string{conn.Src, conn.Dst, conn.ConnString} | ||
if err := writer.Write(row); err != nil { | ||
return "", err | ||
} | ||
} | ||
writer.Flush() | ||
return buf.String(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package connlist | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"strings" | ||
|
||
"github.com/np-guard/netpol-analyzer/pkg/netpol/internal/common" | ||
) | ||
|
||
const ( | ||
ipColor = "red2" | ||
nsPeerColor = "blue" | ||
) | ||
|
||
// formatDOT: implements the connsFormatter interface for dot output format | ||
type formatDOT struct { | ||
} | ||
|
||
// formats an edge line from a singleConnFields struct , to be used for dot graph | ||
func getEdgeLine(c Peer2PeerConnection) string { | ||
connStr := common.ConnStrFromConnProperties(c.AllProtocolsAndPorts(), c.ProtocolsAndPorts()) | ||
srcName, _ := peerNameAndColorByType(c.Src()) | ||
dstName, _ := peerNameAndColorByType(c.Dst()) | ||
return fmt.Sprintf("\t%q -> %q [label=%q color=\"gold2\" fontcolor=\"darkgreen\"]", srcName, dstName, connStr) | ||
} | ||
|
||
func peerNameAndColorByType(peer Peer) (name, color string) { | ||
if peer.IsPeerIPType() { | ||
return peer.String(), ipColor | ||
} else if peer.Name() == common.IngressPodName { | ||
return peer.String(), nsPeerColor | ||
} | ||
return peer.Name(), nsPeerColor | ||
} | ||
|
||
// formats a peer line for dot graph | ||
func getPeerLine(peer Peer) string { | ||
peerName, peerColor := peerNameAndColorByType(peer) | ||
return fmt.Sprintf("\t\t%q [label=%q color=%q fontcolor=%q]", peerName, peerName, peerColor, peerColor) | ||
} | ||
|
||
// returns a dot string form of connections from list of Peer2PeerConnection objects | ||
func (d formatDOT) writeOutput(conns []Peer2PeerConnection) (string, error) { | ||
nsPeers := make(map[string][]string) // map from namespace to its peers (grouping peers by namespaces) | ||
edgeLines := make([]string, len(conns)) // list of edges lines | ||
peersVisited := make(map[string]struct{}, 0) // acts as a set | ||
for index := range conns { | ||
srcStr, dstStr := conns[index].Src().String(), conns[index].Dst().String() | ||
edgeLines[index] = getEdgeLine(conns[index]) | ||
if _, ok := peersVisited[srcStr]; !ok { | ||
peersVisited[srcStr] = struct{}{} | ||
checkAndAddPeerToNsGroup(nsPeers, conns[index].Src()) | ||
} | ||
if _, ok := peersVisited[dstStr]; !ok { | ||
peersVisited[dstStr] = struct{}{} | ||
checkAndAddPeerToNsGroup(nsPeers, conns[index].Dst()) | ||
} | ||
} | ||
// sort graph lines | ||
sort.Strings(edgeLines) | ||
// collect all lines by order | ||
allLines := []string{common.DotHeader} | ||
allLines = append(allLines, addNsGroups(nsPeers)...) | ||
allLines = append(allLines, edgeLines...) | ||
allLines = append(allLines, common.DotClosing) | ||
return strings.Join(allLines, newLineChar), nil | ||
} | ||
|
||
func checkAndAddPeerToNsGroup(mapNsToPeers map[string][]string, peer Peer) { | ||
if _, ok := mapNsToPeers[peer.Namespace()]; !ok { | ||
mapNsToPeers[peer.Namespace()] = []string{} | ||
} | ||
mapNsToPeers[peer.Namespace()] = append(mapNsToPeers[peer.Namespace()], getPeerLine(peer)) | ||
} | ||
|
||
func addNsGroups(nsPeersMap map[string][]string) []string { | ||
res := []string{} | ||
// sort namespaces (map's keys) to ensure same output always | ||
nsKeys := sortMapKeys(nsPeersMap) | ||
// write ns groups | ||
for _, ns := range nsKeys { | ||
peersLines := nsPeersMap[ns] | ||
sort.Strings(peersLines) | ||
// create ns subgraph cluster | ||
nsLabel := strings.ReplaceAll(ns, "-", "_") | ||
nsLines := []string{"\tsubgraph cluster_" + nsLabel + " {"} // subgraph header | ||
nsLines = append(nsLines, peersLines...) | ||
nsLines = append(nsLines, "\t\tlabel=\""+ns+"\"", "\t}") | ||
// add ns section to the res | ||
res = append(res, nsLines...) | ||
} | ||
return res | ||
} | ||
|
||
func sortMapKeys(nsPeersMap map[string][]string) []string { | ||
keys := make([]string, 0, len(nsPeersMap)) | ||
for k := range nsPeersMap { | ||
keys = append(keys, k) | ||
} | ||
sort.Strings(keys) | ||
return keys | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package connlist | ||
|
||
import "encoding/json" | ||
|
||
// formatJSON: implements the connsFormatter interface for JSON output format | ||
type formatJSON struct { | ||
} | ||
|
||
// returns a json string form of connections from list of Peer2PeerConnection objects | ||
func (j formatJSON) writeOutput(conns []Peer2PeerConnection) (string, error) { | ||
// get an array of sorted conns items ([]singleConnFields) | ||
sortedConnItems := sortConnections(conns) | ||
jsonConns, err := json.MarshalIndent(sortedConnItems, "", " ") | ||
if err != nil { | ||
return "", err | ||
} | ||
return string(jsonConns), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package connlist | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"strings" | ||
) | ||
|
||
// formatMD: implements the connsFormatter interface for md output format | ||
type formatMD struct { | ||
} | ||
|
||
// formats the md output header | ||
func getMDHeader() string { | ||
return "| src | dst | conn |\n|-----|-----|------|" | ||
} | ||
|
||
// formats a connection line for md output | ||
func getMDLine(c singleConnFields) string { | ||
return fmt.Sprintf("| %s | %s | %s |", c.Src, c.Dst, c.ConnString) | ||
} | ||
|
||
// returns a md string form of connections from list of Peer2PeerConnection objects | ||
func (md formatMD) writeOutput(conns []Peer2PeerConnection) (string, error) { | ||
mdLines := make([]string, len(conns)) | ||
for index := range conns { | ||
mdLines[index] = getMDLine(formSingleConn(conns[index])) | ||
} | ||
sort.Strings(mdLines) | ||
allLines := []string{getMDHeader()} | ||
allLines = append(allLines, mdLines...) | ||
return strings.Join(allLines, newLineChar), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package connlist | ||
|
||
import ( | ||
"sort" | ||
"strings" | ||
) | ||
|
||
// formatText: implements the connsFormatter interface for txt output format | ||
type formatText struct { | ||
} | ||
|
||
// returns a textual string format of connections from list of Peer2PeerConnection objects | ||
func (t formatText) writeOutput(conns []Peer2PeerConnection) (string, error) { | ||
connLines := make([]string, len(conns)) | ||
for i := range conns { | ||
connLines[i] = formSingleConn(conns[i]).string() | ||
} | ||
sort.Strings(connLines) | ||
return strings.Join(connLines, newLineChar), nil | ||
} |