Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

supporting csv, md and json formats #360

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions pkg/cli/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@ func getRequiredOutputFormatString(validFormats string) string {
return fmt.Sprintf("Required output format (%s)", validFormats)
}

// getListOutputFormatDescription returns the description of the required formats of the list command
// exposure analysis is supported with less formats
func getListOutputFormatDescription() string {
comma := ","
supportedFormats := strings.Join(connlist.ValidFormats, comma)
supportedExposureFormats := strings.Join(connlist.ExposureValidFormats, comma)
return getRequiredOutputFormatString(supportedFormats) + " or (" + supportedExposureFormats + " with exposure analysis) "
}

func runListCommand() error {
var conns []connlist.Peer2PeerConnection
var err error
Expand Down Expand Up @@ -111,7 +102,7 @@ defined`,
k8snetpolicy list -k ./kube/config`,

PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := connlist.ValidateOutputFormat(output, exposureAnalysis); err != nil {
if err := connlist.ValidateOutputFormat(output); err != nil {
return err
}
// call parent pre-run
Expand Down Expand Up @@ -140,7 +131,9 @@ defined`,
"Focus connections of specified workload in the output (<workload-name> or <workload-namespace/workload-name>)")
c.Flags().BoolVarP(&exposureAnalysis, "exposure", "", false, "Turn on exposure analysis and append results to the output")
// output format - default txt
c.Flags().StringVarP(&output, "output", "o", outconsts.DefaultFormat, getListOutputFormatDescription())
// output format - default txt
supportedFormats := strings.Join(connlist.ValidFormats, ",")
c.Flags().StringVarP(&output, "output", "o", outconsts.DefaultFormat, getRequiredOutputFormatString(supportedFormats))
// out file
c.Flags().StringVarP(&outFile, "file", "f", "", "Write output to specified file")

Expand Down
14 changes: 4 additions & 10 deletions pkg/netpol/connlist/connlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ func (ca *ConnlistAnalyzer) ConnlistFromDirPath(dirPath string) ([]Peer2PeerConn
var ValidFormats = []string{output.TextFormat, output.JSONFormat, output.DOTFormat,
output.CSVFormat, output.MDFormat}

var ExposureValidFormats = []string{output.TextFormat, output.DOTFormat}

// ConnlistAnalyzerOption is the type for specifying options for ConnlistAnalyzer,
// using Golang's Options Pattern (https://golang.cafe/blog/golang-functional-options-pattern.html).
type ConnlistAnalyzerOption func(*ConnlistAnalyzer)
Expand Down Expand Up @@ -275,7 +273,7 @@ func (ca *ConnlistAnalyzer) ConnectionsListToString(conns []Peer2PeerConnection)
ca.errors = append(ca.errors, newResultFormattingError(err))
return "", err
}
out, err := connsFormatter.writeOutput(conns, ca.exposureResult)
out, err := connsFormatter.writeOutput(conns, ca.exposureResult, ca.exposureAnalysis)
if err != nil {
ca.errors = append(ca.errors, newResultFormattingError(err))
return "", err
Expand All @@ -284,12 +282,8 @@ func (ca *ConnlistAnalyzer) ConnectionsListToString(conns []Peer2PeerConnection)
}

// validate the value of the output format
func ValidateOutputFormat(format string, exposureFlag bool) error {
formatList := ValidFormats
if exposureFlag {
formatList = ExposureValidFormats
}
for _, formatName := range formatList {
func ValidateOutputFormat(format string) error {
for _, formatName := range ValidFormats {
if format == formatName {
return nil
}
Expand All @@ -299,7 +293,7 @@ func ValidateOutputFormat(format string, exposureFlag bool) error {

// returns the relevant formatter for the analyzer's outputFormat
func (ca *ConnlistAnalyzer) getFormatter() (connsFormatter, error) {
if err := ValidateOutputFormat(ca.outputFormat, ca.exposureAnalysis); err != nil {
if err := ValidateOutputFormat(ca.outputFormat); err != nil {
return nil, err
}
switch ca.outputFormat {
Expand Down
72 changes: 36 additions & 36 deletions pkg/netpol/connlist/connlist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,8 @@ func TestConnlistOutputFatalErrors(t *testing.T) {
{
name: "unsupported_output_format_for_exposure_analysis_should_return_fatal_error",
dirName: "acs-security-demos",
format: "json",
errorStrContains: netpolerrors.FormatNotSupportedErrStr("json"),
format: "gif",
errorStrContains: netpolerrors.FormatNotSupportedErrStr("gif"),
exposureFlag: true,
},
}
Expand Down Expand Up @@ -758,97 +758,97 @@ var goodPathTests = []struct {
{
testDirName: "acs-security-demos",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "acs-security-demos",
exposureAnalysis: true,
// test with focus-workload that appears in exposure-analysis result
focusWorkload: "frontend/webapp",
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "acs-security-demos",
exposureAnalysis: true,
// test with focus-workload that does not appear in exposure-analysis result
focusWorkload: "backend/catalog",
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_allow_all",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_allow_all_in_cluster",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_allow_egress_deny_ingress",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_allow_ingress_deny_egress",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_matched_and_unmatched_rules",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_matched_and_unmatched_rules",
exposureAnalysis: true,
focusWorkload: "hello-world/workload-a",
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_only_matched_rules",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_multiple_unmatched_rules",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_new_namespace_conn_and_entire_cluster",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_same_unmatched_rule_in_ingress_egress",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_with_no_netpols",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_egress_to_entire_cluster_with_named_ports",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_ingress_from_entire_cluster_with_named_ports",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_egress_exposure_with_named_port",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_exposure_to_namespace_with_multiple_labels",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_pod_exposed_only_to_representative_peers",
Expand All @@ -858,60 +858,60 @@ var goodPathTests = []struct {
{
testDirName: "test_pod_exposed_only_to_representative_peers",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_conn_entire_cluster_with_empty_selectors",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_conn_to_all_pods_in_a_new_ns",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_conn_with_new_pod_selector_and_ns_selector",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_conn_with_only_pod_selector",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_conn_with_pod_selector_in_any_ns",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "onlineboutique_workloads",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "onlineboutique_workloads",
exposureAnalysis: true,
focusWorkload: "default/loadgenerator",
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "k8s_ingress_test_new",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "k8s_ingress_test_new",
exposureAnalysis: true,
focusWorkload: "details-v1-79f774bdb9",
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "k8s_ingress_test",
exposureAnalysis: true,
focusWorkload: "ratings-v1-b6994bb9",
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_exposure_minimal_netpol_analysis",
Expand All @@ -923,22 +923,22 @@ var goodPathTests = []struct {
// if there is a matching pod in a specific namespace
testDirName: "test_exposure_to_any_namespace_with_podSelector",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_conn_to_all_pods_in_an_existing_ns",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_conn_to_new_pod_in_an_existing_ns",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
testDirName: "test_conn_to_all_pods_in_an_existing_ns_with_ns_selector_only",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
{
// following test resources : contains two pods in different namespaces, and two policies, one for each namespace
Expand All @@ -954,6 +954,6 @@ var goodPathTests = []struct {

testDirName: "test_exposure_to_namespace_except_specific_pod",
exposureAnalysis: true,
outputFormats: ExposureValidFormats,
outputFormats: ValidFormats,
},
}
Loading