diff --git a/node/node.go b/node/node.go index 134ff628d..214de55d0 100644 --- a/node/node.go +++ b/node/node.go @@ -101,6 +101,10 @@ func (s *Service) DeleteCollection(ctx context.Context, lopts metav1.ListOptions return xerrors.Errorf("list nodes: %w", err) } eg, ctx := errgroup.WithContext(ctx) + nsList, err := s.client.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) + if err != nil { + return xerrors.Errorf("list namespaces: %w", err) + } for _, n := range ns.Items { n := n eg.Go(func() error { @@ -108,9 +112,11 @@ func (s *Service) DeleteCollection(ctx context.Context, lopts metav1.ListOptions lopts := metav1.ListOptions{ FieldSelector: "spec.nodeName=" + n.Name, } - // This method deletes all pods on all namespaces scheduled to the specified node. - if err := s.podService.DeleteCollection(ctx, metav1.NamespaceAll, lopts); err != nil { - return xerrors.Errorf("failed to delete pods on node %s: %w\n", n.Name, err) + // This method deletes all pods on specified namespace scheduled to the specified node. + for _, ns := range nsList.Items { + if err := s.podService.DeleteCollection(ctx, ns.GetName(), lopts); err != nil { + return xerrors.Errorf("failed to delete pods on node %s: %w\n", n.Name, err) + } } // delete specific node diff --git a/node/node_test.go b/node/node_test.go index 36cf8737c..467b0a12f 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -178,6 +178,11 @@ func TestService_DeleteCollection(t *testing.T) { }, prepareFakeClientSetFn: func() *fake.Clientset { c := fake.NewSimpleClientset() + c.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default", + }, + }, metav1.CreateOptions{}) c.CoreV1().Nodes().Create(context.Background(), &corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "node1", @@ -204,6 +209,11 @@ func TestService_DeleteCollection(t *testing.T) { }, prepareFakeClientSetFn: func() *fake.Clientset { c := fake.NewSimpleClientset() + c.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default", + }, + }, metav1.CreateOptions{}) c.CoreV1().Nodes().Create(context.Background(), &corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "node1", @@ -225,6 +235,19 @@ func TestService_DeleteCollection(t *testing.T) { }, prepareFakeClientSetFn: func() *fake.Clientset { c := fake.NewSimpleClientset() + c.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default", + }, + }, metav1.CreateOptions{}) + c.CoreV1().Pods("default").Create(context.Background(), &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + }, + Spec: corev1.PodSpec{ + NodeName: "node1", + }, + }, metav1.CreateOptions{}) c.CoreV1().Nodes().Create(context.Background(), &corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "node1", @@ -237,6 +260,59 @@ func TestService_DeleteCollection(t *testing.T) { }, wantErr: true, }, + { + name: "delete nodes with multiple existing namespaced pods", + preparePodServiceMockFn: func(m *mock_node.MockPodService) { + m.EXPECT().DeleteCollection(gomock.Any(), "default1", metav1.ListOptions{ + FieldSelector: "spec.nodeName=node1", + }).Return(nil) + m.EXPECT().DeleteCollection(gomock.Any(), "default2", metav1.ListOptions{ + FieldSelector: "spec.nodeName=node1", + }).Return(nil) + m.EXPECT().DeleteCollection(gomock.Any(), "default3", metav1.ListOptions{ + FieldSelector: "spec.nodeName=node1", + }).Return(errors.New("error")) + }, + prepareFakeClientSetFn: func() *fake.Clientset { + c := fake.NewSimpleClientset() + c.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default1", + }, + }, metav1.CreateOptions{}) + c.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default2", + }, + }, metav1.CreateOptions{}) + c.CoreV1().Pods("default1").Create(context.Background(), &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + }, + Spec: corev1.PodSpec{ + NodeName: "node1", + }, + }, metav1.CreateOptions{}) + c.CoreV1().Pods("default2").Create(context.Background(), &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod2", + }, + Spec: corev1.PodSpec{ + NodeName: "node1", + }, + }, metav1.CreateOptions{}) + c.CoreV1().Nodes().Create(context.Background(), &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node1", + }, + }, metav1.CreateOptions{}) + return c + }, + lopts: metav1.ListOptions{ + FieldSelector: "spec.nodeName!=", + }, + wantErr: false, + }, } for _, tt := range tests { tt := tt diff --git a/reset/reset.go b/reset/reset.go index 42d9ad6c8..af251c5c9 100644 --- a/reset/reset.go +++ b/reset/reset.go @@ -51,16 +51,23 @@ func NewResetService( // Reset cleans up all resources and scheduler configuration. func (s *Service) Reset(ctx context.Context) error { eg, ctx := errgroup.WithContext(ctx) + nsList, err := s.client.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) + if err != nil { + return xerrors.Errorf("list namespaces: %w", err) + } for k, ds := range s.deleteServicesForNamespacedResources { ds := ds k := k - eg.Go(func() error { - // this method deletes all resources on all namespaces. - if err := ds.DeleteCollection(ctx, metav1.NamespaceAll, metav1.ListOptions{}); err != nil { - return xerrors.Errorf("delete collecton of %s service: %w", k, err) - } - return nil - }) + for _, ns := range nsList.Items { + ns := ns + eg.Go(func() error { + // this method deletes all resources on specified namespace. + if err := ds.DeleteCollection(ctx, ns.GetName(), metav1.ListOptions{}); err != nil { + return xerrors.Errorf("delete collecton of %s service: %w", k, err) + } + return nil + }) + } } for k, ds := range s.deleteServices { ds := ds