diff --git a/pkg/cli/command_test.go b/pkg/cli/command_test.go index 34852b70..6566a748 100644 --- a/pkg/cli/command_test.go +++ b/pkg/cli/command_test.go @@ -350,7 +350,10 @@ func TestEvalCommandOutput(t *testing.T) { cases := []struct { dir string sourcePod string + sourceNs string + destNs string destPod string + protocol string port string evalResult bool }{ @@ -368,13 +371,71 @@ func TestEvalCommandOutput(t *testing.T) { port: "80", evalResult: false, }, + { + dir: "anp_demo", + sourceNs: "gryffindor", + sourcePod: "harry-potter-1", + destPod: "luna-lovegood-1", + destNs: "ravenclaw", + protocol: "udp", + port: "52", + evalResult: true, + }, + { + dir: "anp_test_6", + sourceNs: "network-policy-conformance-slytherin", + sourcePod: "draco-malfoy-1", + destPod: "cedric-diggory-1", + destNs: "network-policy-conformance-hufflepuff", + protocol: "udp", + port: "5353", + evalResult: false, + }, + { + dir: "anp_test_multiple_anps", + sourceNs: "network-policy-conformance-ravenclaw", + sourcePod: "luna-lovegood-1", + destPod: "draco-malfoy-1", + destNs: "network-policy-conformance-slytherin", + protocol: "sctp", + port: "9003", + evalResult: false, + }, + { + dir: "anp_with_np_and_banp_pass_test", + sourceNs: "ns2", + sourcePod: "pod1-1", + destPod: "pod1-1", + destNs: "ns1", + port: "80", + evalResult: true, + }, + { + dir: "anp_with_np_pass_test", + sourceNs: "ns2", + sourcePod: "pod1-1", + destPod: "pod1-1", + destNs: "ns1", + port: "8080", + evalResult: false, + }, } for _, tt := range cases { tt := tt testName := "eval_" + tt.dir + "_from_" + tt.sourcePod + "_to_" + tt.destPod t.Run(testName, func(t *testing.T) { + if tt.protocol == "" { + tt.protocol = defaultProtocol + } + if tt.sourceNs == "" { + tt.sourceNs = defaultNs + } + if tt.destNs == "" { + tt.destNs = defaultNs + } args := []string{"eval", "--dirpath", testutils.GetTestDirPath(tt.dir), - "-s", tt.sourcePod, "-d", tt.destPod, "-p", tt.port} + "-s", tt.sourcePod, "-d", tt.destPod, "-p", tt.port, "--protocol", tt.protocol, + "-n", tt.sourceNs, "--destination-namespace", tt.destNs} actualOut, err := buildAndExecuteCommand(args) require.Nil(t, err, "test: %q", testName) require.Contains(t, actualOut, fmt.Sprintf("%v", tt.evalResult), diff --git a/pkg/cli/evaluate.go b/pkg/cli/evaluate.go index f99aec3c..70ba6e31 100644 --- a/pkg/cli/evaluate.go +++ b/pkg/cli/evaluate.go @@ -29,11 +29,16 @@ import ( // Currently adds many options flags, so wait until cobra supports something // like NamedFlagSet's. +const ( + defaultNs = "default" + defaultProtocol = "tcp" +) + var ( // evaluated connection information - protocol = "tcp" - sourcePod = types.NamespacedName{Namespace: "default"} - destinationPod = types.NamespacedName{Namespace: "default"} + protocol = defaultProtocol + sourcePod = types.NamespacedName{Namespace: defaultNs} + destinationPod = types.NamespacedName{Namespace: defaultNs} srcExternalIP string dstExternalIP string port string @@ -63,6 +68,7 @@ func validateEvalFlags() error { return nil } +//gocyclo:ignore func updatePolicyEngineObjectsFromDirPath(pe *eval.PolicyEngine, podNames []types.NamespacedName) error { // get relevant resources from dir path eLogger := logger.NewDefaultLoggerWithVerbosity(determineLogVerbosity()) @@ -92,12 +98,33 @@ func updatePolicyEngineObjectsFromDirPath(pe *eval.PolicyEngine, podNames []type for i := range objectsList { obj := objectsList[i] switch obj.Kind { + // workloads kinds case parser.Pod: err = pe.InsertObject(obj.Pod) + case parser.ReplicaSet: + err = pe.InsertObject(obj.ReplicaSet) + case parser.Deployment: + err = pe.InsertObject(obj.Deployment) + case parser.DaemonSet: + err = pe.InsertObject(obj.DaemonSet) + case parser.StatefulSet: + err = pe.InsertObject(obj.StatefulSet) + case parser.ReplicationController: + err = pe.InsertObject(obj.ReplicationController) + case parser.Job: + err = pe.InsertObject(obj.Job) + case parser.CronJob: + err = pe.InsertObject(obj.CronJob) + // ns kind case parser.Namespace: err = pe.InsertObject(obj.Namespace) + // netpols kinds case parser.NetworkPolicy: err = pe.InsertObject(obj.NetworkPolicy) + case parser.AdminNetworkPolicy: + err = pe.InsertObject(obj.AdminNetworkPolicy) + case parser.BaselineAdminNetworkPolicy: + err = pe.InsertObject(obj.BaselineAdminNetworkPolicy) default: continue } diff --git a/pkg/manifests/parser/k8sobj.go b/pkg/manifests/parser/k8sobj.go index a8fe697a..1477c3e8 100644 --- a/pkg/manifests/parser/k8sobj.go +++ b/pkg/manifests/parser/k8sobj.go @@ -211,6 +211,8 @@ var policyKinds = map[string]bool{ BaselineAdminNetworkPolicy: true, } +//nolint:funlen // cases may not be shorten +//gocyclo:ignore func FilterObjectsList(allObjects []K8sObject, podNames []types.NamespacedName) []K8sObject { podNamesMap := make(map[string]bool, 0) nsMap := make(map[string]bool, 0) @@ -234,6 +236,40 @@ func FilterObjectsList(allObjects []K8sObject, podNames []types.NamespacedName) if _, ok := podNamesMap[types.NamespacedName{Name: obj.Pod.Name, Namespace: obj.Pod.Namespace}.String()]; ok { res = append(res, obj) } + // the input pod-names is the name of the pod (replica); + // so if the manifest resources contain a "workload" type (other than Pod); + // the pod name is actually a name of a replica of the workload, and not the name of the workload (obj.Name); + // so here we will compare only namespaces; + // and podName will be compared later after creating the pods (replicas) from the + // workload in the eval package + case StatefulSet: + if _, ok := nsMap[obj.StatefulSet.Namespace]; ok { + res = append(res, obj) + } + case DaemonSet: + if _, ok := nsMap[obj.DaemonSet.Namespace]; ok { + res = append(res, obj) + } + case Deployment: + if _, ok := nsMap[obj.Deployment.Namespace]; ok { + res = append(res, obj) + } + case ReplicaSet: + if _, ok := nsMap[obj.ReplicaSet.Namespace]; ok { + res = append(res, obj) + } + case Job: + if _, ok := nsMap[obj.Job.Namespace]; ok { + res = append(res, obj) + } + case CronJob: + if _, ok := nsMap[obj.CronJob.Namespace]; ok { + res = append(res, obj) + } + case ReplicationController: + if _, ok := nsMap[obj.ReplicationController.Namespace]; ok { + res = append(res, obj) + } case Service: if _, ok := nsMap[obj.Service.Namespace]; ok { res = append(res, obj) @@ -246,6 +282,10 @@ func FilterObjectsList(allObjects []K8sObject, podNames []types.NamespacedName) if _, ok := nsMap[obj.Ingress.Namespace]; ok { res = append(res, obj) } + case AdminNetworkPolicy: + res = append(res, obj) + case BaselineAdminNetworkPolicy: + res = append(res, obj) default: continue }