diff --git a/pkg/analyzer/cronjob.go b/pkg/analyzer/cronjob.go index 7a2e2dde32..29b0c52a26 100644 --- a/pkg/analyzer/cronjob.go +++ b/pkg/analyzer/cronjob.go @@ -22,7 +22,7 @@ func (analyzer CronJobAnalyzer) Analyze(a common.Analyzer) ([]common.Result, err var results []common.Result - cronJobList, err := a.Client.GetClient().BatchV1().CronJobs("").List(a.Context, v1.ListOptions{}) + cronJobList, err := a.Client.GetClient().BatchV1().CronJobs(a.Namespace).List(a.Context, v1.ListOptions{}) if err != nil { return results, err } diff --git a/pkg/analyzer/cronjob_test.go b/pkg/analyzer/cronjob_test.go index 0290b5439d..f17e59d3f4 100644 --- a/pkg/analyzer/cronjob_test.go +++ b/pkg/analyzer/cronjob_test.go @@ -124,3 +124,97 @@ func TestCronJobBroken(t *testing.T) { assert.Equal(t, analysisResults[0].Name, "default/example-cronjob") assert.Equal(t, analysisResults[0].Kind, "CronJob") } + +func TestCronJobBrokenMultipleNamespaceFiltering(t *testing.T) { + clientset := fake.NewSimpleClientset( + &batchv1.CronJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example-cronjob", + Namespace: "default", + Annotations: map[string]string{ + "analysisDate": "2022-04-01", + }, + Labels: map[string]string{ + "app": "example-app", + }, + }, + Spec: batchv1.CronJobSpec{ + Schedule: "*** * * * *", + ConcurrencyPolicy: "Allow", + JobTemplate: batchv1.JobTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app": "example-app", + }, + }, + Spec: batchv1.JobSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "example-container", + Image: "nginx", + }, + }, + RestartPolicy: v1.RestartPolicyOnFailure, + }, + }, + }, + }, + }, + }, + &batchv1.CronJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example-cronjob", + Namespace: "other-namespace", + Annotations: map[string]string{ + "analysisDate": "2022-04-01", + }, + Labels: map[string]string{ + "app": "example-app", + }, + }, + Spec: batchv1.CronJobSpec{ + Schedule: "*** * * * *", + ConcurrencyPolicy: "Allow", + JobTemplate: batchv1.JobTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app": "example-app", + }, + }, + Spec: batchv1.JobSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "example-container", + Image: "nginx", + }, + }, + RestartPolicy: v1.RestartPolicyOnFailure, + }, + }, + }, + }, + }, + }) + + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + + analyzer := CronJobAnalyzer{} + analysisResults, err := analyzer.Analyze(config) + if err != nil { + t.Error(err) + } + + assert.Equal(t, len(analysisResults), 1) + assert.Equal(t, analysisResults[0].Name, "default/example-cronjob") + assert.Equal(t, analysisResults[0].Kind, "CronJob") +} diff --git a/pkg/analyzer/deployment.go b/pkg/analyzer/deployment.go index bc89b8e849..e34755403c 100644 --- a/pkg/analyzer/deployment.go +++ b/pkg/analyzer/deployment.go @@ -23,7 +23,7 @@ func (d DeploymentAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) "analyzer_name": kind, }) - deployments, err := a.Client.GetClient().AppsV1().Deployments("").List(context.Background(), v1.ListOptions{}) + deployments, err := a.Client.GetClient().AppsV1().Deployments(a.Namespace).List(context.Background(), v1.ListOptions{}) if err != nil { return nil, err } diff --git a/pkg/analyzer/deployment_test.go b/pkg/analyzer/deployment_test.go index 1365c85bab..88ae4dbc8d 100644 --- a/pkg/analyzer/deployment_test.go +++ b/pkg/analyzer/deployment_test.go @@ -60,3 +60,81 @@ func TestDeploymentAnalyzer(t *testing.T) { assert.Equal(t, analysisResults[0].Kind, "Deployment") assert.Equal(t, analysisResults[0].Name, "default/example") } + +func TestDeploymentAnalyzerNamespaceFiltering(t *testing.T) { + clientset := fake.NewSimpleClientset( + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + }, + Spec: appsv1.DeploymentSpec{ + Replicas: func() *int32 { i := int32(3); return &i }(), + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "example-container", + Image: "nginx", + Ports: []v1.ContainerPort{ + { + ContainerPort: 80, + }, + }, + }, + }, + }, + }, + }, + Status: appsv1.DeploymentStatus{ + Replicas: 2, + AvailableReplicas: 1, + }, + }, + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "other-namespace", + }, + Spec: appsv1.DeploymentSpec{ + Replicas: func() *int32 { i := int32(3); return &i }(), + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "example-container", + Image: "nginx", + Ports: []v1.ContainerPort{ + { + ContainerPort: 80, + }, + }, + }, + }, + }, + }, + }, + Status: appsv1.DeploymentStatus{ + Replicas: 2, + AvailableReplicas: 1, + }, + }, + ) + + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + + deploymentAnalyzer := DeploymentAnalyzer{} + analysisResults, err := deploymentAnalyzer.Analyze(config) + if err != nil { + t.Error(err) + } + assert.Equal(t, len(analysisResults), 1) + assert.Equal(t, analysisResults[0].Kind, "Deployment") + assert.Equal(t, analysisResults[0].Name, "default/example") +} diff --git a/pkg/analyzer/hpaAnalyzer_test.go b/pkg/analyzer/hpaAnalyzer_test.go index dfe9f13f0c..e5d7e32d82 100644 --- a/pkg/analyzer/hpaAnalyzer_test.go +++ b/pkg/analyzer/hpaAnalyzer_test.go @@ -204,3 +204,34 @@ func TestHPAAnalyzerWithExistingScaleTargetRef(t *testing.T) { assert.Equal(t, len(analysis.Error), 0) } } + +func TestHPAAnalyzerNamespaceFiltering(t *testing.T) { + clientset := fake.NewSimpleClientset( + &autoscalingv1.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + Annotations: map[string]string{}, + }, + }, + &autoscalingv1.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "other-namespace", + Annotations: map[string]string{}, + }, + }) + hpaAnalyzer := HpaAnalyzer{} + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + analysisResults, err := hpaAnalyzer.Analyze(config) + if err != nil { + t.Error(err) + } + assert.Equal(t, len(analysisResults), 1) +} diff --git a/pkg/analyzer/ingress_test.go b/pkg/analyzer/ingress_test.go index 54f149b49b..65293e9cba 100644 --- a/pkg/analyzer/ingress_test.go +++ b/pkg/analyzer/ingress_test.go @@ -113,3 +113,35 @@ func TestIngressAnalyzerWithoutIngressClassAnnotation(t *testing.T) { t.Error("expected error 'does not specify an Ingress class' not found in analysis results") } } + +func TestIngressAnalyzerNamespaceFiltering(t *testing.T) { + clientset := fake.NewSimpleClientset( + &networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + Annotations: map[string]string{}, + }, + }, + &networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "other-namespace", + Annotations: map[string]string{}, + }, + }) + ingressAnalyzer := IngressAnalyzer{} + + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + analysisResults, err := ingressAnalyzer.Analyze(config) + if err != nil { + t.Error(err) + } + assert.Equal(t, len(analysisResults), 1) +} diff --git a/pkg/analyzer/netpol_test.go b/pkg/analyzer/netpol_test.go index e3fcc87a56..f4f2812168 100644 --- a/pkg/analyzer/netpol_test.go +++ b/pkg/analyzer/netpol_test.go @@ -120,3 +120,77 @@ func TestNetpolWithPod(t *testing.T) { assert.Equal(t, len(results), 0) } + +func TestNetpolNoPodsNamespaceFiltering(t *testing.T) { + clientset := fake.NewSimpleClientset( + &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "example", + }, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "database", + }, + }, + }, + }, + }, + }, + }, + }, + &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "other-namespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "example", + }, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + { + From: []networkingv1.NetworkPolicyPeer{ + { + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "database", + }, + }, + }, + }, + }, + }, + }, + }) + + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + + analyzer := NetworkPolicyAnalyzer{} + results, err := analyzer.Analyze(config) + if err != nil { + t.Error(err) + } + + assert.Equal(t, len(results), 1) + assert.Equal(t, results[0].Kind, "NetworkPolicy") + +} diff --git a/pkg/analyzer/pod_test.go b/pkg/analyzer/pod_test.go index e23eeb19a4..03e11b9180 100644 --- a/pkg/analyzer/pod_test.go +++ b/pkg/analyzer/pod_test.go @@ -47,3 +47,57 @@ func TestPodAnalyzer(t *testing.T) { } assert.Equal(t, len(analysisResults), 1) } + +func TestPodAnalyzerNamespaceFiltering(t *testing.T) { + + clientset := fake.NewSimpleClientset( + &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + Annotations: map[string]string{}, + }, + Status: v1.PodStatus{ + Phase: v1.PodPending, + Conditions: []v1.PodCondition{ + { + Type: v1.PodScheduled, + Reason: "Unschedulable", + Message: "0/1 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.", + }, + }, + }, + }, + &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "other-namespace", + Annotations: map[string]string{}, + }, + Status: v1.PodStatus{ + Phase: v1.PodPending, + Conditions: []v1.PodCondition{ + { + Type: v1.PodScheduled, + Reason: "Unschedulable", + Message: "0/1 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.", + }, + }, + }, + }) + + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + podAnalyzer := PodAnalyzer{} + var analysisResults []common.Result + analysisResults, err := podAnalyzer.Analyze(config) + if err != nil { + t.Error(err) + } + assert.Equal(t, len(analysisResults), 1) +} diff --git a/pkg/analyzer/service_test.go b/pkg/analyzer/service_test.go index 68755704ba..bfd80f2c11 100644 --- a/pkg/analyzer/service_test.go +++ b/pkg/analyzer/service_test.go @@ -48,3 +48,62 @@ func TestServiceAnalyzer(t *testing.T) { } assert.Equal(t, len(analysisResults), 1) } + +func TestServiceAnalyzerNamespaceFiltering(t *testing.T) { + + clientset := fake.NewSimpleClientset( + &v1.Endpoints{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + Annotations: map[string]string{}, + }, + }, + &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + Annotations: map[string]string{}, + }, + Spec: v1.ServiceSpec{ + Selector: map[string]string{ + "app": "example", + }, + }, + }, + &v1.Endpoints{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "other-namespace", + Annotations: map[string]string{}, + }, + }, + &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "other-namespace", + Annotations: map[string]string{}, + }, + Spec: v1.ServiceSpec{ + Selector: map[string]string{ + "app": "example", + }, + }, + }, + ) + + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + + serviceAnalyzer := ServiceAnalyzer{} + analysisResults, err := serviceAnalyzer.Analyze(config) + if err != nil { + t.Error(err) + } + assert.Equal(t, len(analysisResults), 1) +} diff --git a/pkg/analyzer/statefulset_test.go b/pkg/analyzer/statefulset_test.go index 2cea9dd7a8..faf57e8cc8 100644 --- a/pkg/analyzer/statefulset_test.go +++ b/pkg/analyzer/statefulset_test.go @@ -145,3 +145,33 @@ func TestStatefulSetAnalyzerMissingStorageClass(t *testing.T) { } } + +func TestStatefulSetAnalyzerNamespaceFiltering(t *testing.T) { + clientset := fake.NewSimpleClientset( + &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "default", + }, + }, + &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example", + Namespace: "other-namespace", + }, + }) + statefulSetAnalyzer := StatefulSetAnalyzer{} + + config := common.Analyzer{ + Client: &kubernetes.Client{ + Client: clientset, + }, + Context: context.Background(), + Namespace: "default", + } + analysisResults, err := statefulSetAnalyzer.Analyze(config) + if err != nil { + t.Error(err) + } + assert.Equal(t, len(analysisResults), 1) +}