Repository: pingcap/chaos-mesh
Pull request #556 (2020-05-25 18:47:02)

Support pods filtering by selectors
Signed-off-by: yeya24 <yb532204897@gmail.com>

### What problem does this PR solve? <!--add and issue link with summary if exists-->

This PR updates the list pods interface to `POST` in order to keep the Selector field.

codecov-commenter: # [Codecov](https://codecov.io/gh/pingcap/chaos-mesh/pull/556?src=pr&el=h1) Report
> Merging [#556](https://codecov.io/gh/pingcap/chaos-mesh/pull/556?src=pr&el=desc) into [master](https://codecov.io/gh/pingcap/chaos-mesh/commit/55fef1bf1454c7099f36c5dfd8416ae0f0721a56&el=desc) will **decrease** coverage by `5.20%`.
> The diff coverage is `40.84%`.

[![Impacted file tree graph](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/graphs/tree.svg?width=650&height=150&src=pr&token=a3XIzuy5Dk)](https://codecov.io/gh/pingcap/chaos-mesh/pull/556?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #556      +/-   ##
==========================================
- Coverage   61.39%   56.19%   -5.21%     
==========================================
  Files          64       67       +3     
  Lines        4069     4305     +236     
==========================================
- Hits         2498     2419      -79     
- Misses       1383     1716     +333     
+ Partials      188      170      -18     
```


| [Impacted Files](https://codecov.io/gh/pingcap/chaos-mesh/pull/556?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [controllers/kernelchaos\_controller.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-Y29udHJvbGxlcnMva2VybmVsY2hhb3NfY29udHJvbGxlci5nbw==) | `0.00% <0.00%> (ø)` | |
| [controllers/podchaos/types.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-Y29udHJvbGxlcnMvcG9kY2hhb3MvdHlwZXMuZ28=) | `65.95% <0.00%> (ø)` | |
| [controllers/stresschaos\_controller.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-Y29udHJvbGxlcnMvc3RyZXNzY2hhb3NfY29udHJvbGxlci5nbw==) | `0.00% <0.00%> (ø)` | |
| [pkg/chaosdaemon/netem\_linux.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-cGtnL2NoYW9zZGFlbW9uL25ldGVtX2xpbnV4Lmdv) | `26.66% <0.00%> (ø)` | |
| [pkg/chaosdaemon/netlink\_linux.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-cGtnL2NoYW9zZGFlbW9uL25ldGxpbmtfbGludXguZ28=) | `0.00% <ø> (ø)` | |
| [pkg/chaosdaemon/stress\_server\_linux.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-cGtnL2NoYW9zZGFlbW9uL3N0cmVzc19zZXJ2ZXJfbGludXguZ28=) | `0.00% <0.00%> (ø)` | |
| [pkg/utils/chaosdaemon.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-cGtnL3V0aWxzL2NoYW9zZGFlbW9uLmdv) | `51.21% <ø> (ø)` | |
| [pkg/utils/selector.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-cGtnL3V0aWxzL3NlbGVjdG9yLmdv) | `52.08% <ø> (-0.40%)` | :arrow_down: |
| [pkg/webhook/config/config.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-cGtnL3dlYmhvb2svY29uZmlnL2NvbmZpZy5nbw==) | `17.14% <ø> (-72.86%)` | :arrow_down: |
| [pkg/webhook/config/watcher/config.go](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree#diff-cGtnL3dlYmhvb2svY29uZmlnL3dhdGNoZXIvY29uZmlnLmdv) | `41.66% <ø> (-58.34%)` | :arrow_down: |
| ... and [52 more](https://codecov.io/gh/pingcap/chaos-mesh/pull/556/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pingcap/chaos-mesh/pull/556?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pingcap/chaos-mesh/pull/556?src=pr&el=footer). Last update [45d798a...0406bb9](https://codecov.io/gh/pingcap/chaos-mesh/pull/556?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

cwen0: /merge
sre-bot: /run-all-tests
sre-bot: /run-all-tests
sre-bot: @yeya24 merge failed.
zhouqiang-cl: /merge
sre-bot: /run-all-tests
sre-bot: @yeya24 merge failed.
cwen0: @yeya24 Fix CI, Thanks!
cwen0: /merge
sre-bot: /run-all-tests
sre-bot: @yeya24 merge failed.
cwen0: /merge
sre-bot: /run-all-tests

Patch:
diff --git a/pkg/apiserver/common/common.go b/pkg/apiserver/common/common.go
index ce35f78c..0f5822d6 100644
--- a/pkg/apiserver/common/common.go
+++ b/pkg/apiserver/common/common.go
@@ -21,8 +21,10 @@ import (
 	"github.com/gin-gonic/gin"
 
 	"github.com/pingcap/chaos-mesh/api/v1alpha1"
+	"github.com/pingcap/chaos-mesh/pkg/apiserver/experiment"
 	"github.com/pingcap/chaos-mesh/pkg/apiserver/utils"
 	"github.com/pingcap/chaos-mesh/pkg/config"
+	pkgutils "github.com/pingcap/chaos-mesh/pkg/utils"
 
 	v1 "k8s.io/api/core/v1"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -33,6 +35,7 @@ type Pod struct {
 	Name      string `json:"name"`
 	IP        string `json:"ip"`
 	Namespace string `json:"namespace"`
+	State     string `json:"state"`
 }
 
 // Service defines a handler service for cluster common objects.
@@ -56,7 +59,7 @@ func NewService(
 func Register(r *gin.RouterGroup, s *Service) {
 	endpoint := r.Group("/common")
 
-	endpoint.GET("/pods", s.getPods)
+	endpoint.POST("/pods", s.listPods)
 	endpoint.GET("/namespaces", s.getNamespaces)
 	endpoint.GET("/kinds", s.getKinds)
 
@@ -66,30 +69,32 @@ func Register(r *gin.RouterGroup, s *Service) {
 // @Description Get pods from Kubernetes cluster.
 // @Tags common
 // @Produce json
-// @Param namespace query string false "namespace"
+// @Param request body experiment.SelectorInfo true "Request body"
 // @Success 200 {array} Pod
-// @Router /api/common/pods [get]
+// @Router /api/common/pods [post]
 // @Failure 500 {object} utils.APIError
-func (s *Service) getPods(c *gin.Context) {
-	listOptions := &client.ListOptions{}
-	ns := c.Query("namespace")
-	if ns != "" {
-		listOptions.Namespace = ns
+func (s *Service) listPods(c *gin.Context) {
+	exp := &experiment.SelectorInfo{}
+	if err := c.ShouldBindJSON(exp); err != nil {
+		c.Status(http.StatusBadRequest)
+		_ = c.Error(utils.ErrInvalidRequest.WrapWithNoMessage(err))
+		return
 	}
-
-	var podList v1.PodList
-	if err := s.kubeCli.List(context.Background(), &podList, listOptions); err != nil {
+	ctx := context.TODO()
+	filteredPods, err := pkgutils.SelectPods(ctx, s.kubeCli, exp.ParseSelector())
+	if err != nil {
 		c.Status(http.StatusInternalServerError)
 		_ = c.Error(utils.ErrInternalServer.WrapWithNoMessage(err))
 		return
 	}
 
-	pods := make([]Pod, 0, len(podList.Items))
-	for _, pod := range podList.Items {
+	pods := make([]Pod, 0, len(filteredPods))
+	for _, pod := range filteredPods {
 		pods = append(pods, Pod{
 			Name:      pod.Name,
 			IP:        pod.Status.PodIP,
 			Namespace: pod.Namespace,
+			State:     string(pod.Status.Phase),
 		})
 	}
 
diff --git a/pkg/apiserver/experiment/experiment.go b/pkg/apiserver/experiment/experiment.go
index 526b6a96..cf50df46 100644
--- a/pkg/apiserver/experiment/experiment.go
+++ b/pkg/apiserver/experiment/experiment.go
@@ -104,17 +104,23 @@ type ExperimentInfo struct {
 
 // ScopeInfo defines the scope of the Experiment.
 type ScopeInfo struct {
+	SelectorInfo
+	Mode  string `json:"mode" binding:"oneof='' 'one' 'all' 'fixed' 'fixed' 'fixed-percent' 'random-max-percent'"`
+	Value string `json:"value" binding:"ValueValid"`
+}
+
+// TODO: consider moving this to a common package
+// SelectorInfo defines the selector options of the Experiment.
+type SelectorInfo struct {
 	NamespaceSelectors  []string          `json:"namespace_selectors" binding:"NamespaceSelectorsValid"`
 	LabelSelectors      map[string]string `json:"label_selectors" binding:"MapSelectorsValid"`
 	AnnotationSelectors map[string]string `json:"annotation_selectors" binding:"MapSelectorsValid"`
 	FieldSelectors      map[string]string `json:"field_selectors" binding:"MapSelectorsValid"`
 	PhaseSelector       []string          `json:"phase_selectors" binding:"PhaseSelectorsValid"`
-
-	Mode  string `json:"mode" binding:"oneof='' 'one' 'all' 'fixed' 'fixed' 'fixed-percent' 'random-max-percent'"`
-	Value string `json:"value" binding:"ValueValid"`
 }
 
-func (s *ScopeInfo) parseSelector() v1alpha1.SelectorSpec {
+// ParseSelector parses SelectorInfo to v1alpha1.SelectorSpec
+func (s *SelectorInfo) ParseSelector() v1alpha1.SelectorSpec {
 	selector := v1alpha1.SelectorSpec{}
 
 	for _, ns := range s.NamespaceSelectors {
@@ -279,7 +285,7 @@ func (s *Service) createPodChaos(exp *ExperimentInfo) error {
 			Annotations: exp.Annotations,
 		},
 		Spec: v1alpha1.PodChaosSpec{
-			Selector:      exp.Scope.parseSelector(),
+			Selector:      exp.Scope.ParseSelector(),
 			Action:        v1alpha1.PodChaosAction(exp.Target.PodChaos.Action),
 			Mode:          v1alpha1.PodMode(exp.Scope.Mode),
 			Value:         exp.Scope.Value,
@@ -307,7 +313,7 @@ func (s *Service) createNetworkChaos(exp *ExperimentInfo) error {
 			Annotations: exp.Annotations,
 		},
 		Spec: v1alpha1.NetworkChaosSpec{
-			Selector:  exp.Scope.parseSelector(),
+			Selector:  exp.Scope.ParseSelector(),
 			Action:    v1alpha1.NetworkChaosAction(exp.Target.NetworkChaos.Action),
 			Mode:      v1alpha1.PodMode(exp.Scope.Mode),
 			Value:     exp.Scope.Value,
@@ -330,7 +336,7 @@ func (s *Service) createNetworkChaos(exp *ExperimentInfo) error {
 
 	if exp.Target.NetworkChaos.TargetScope != nil {
 		chaos.Spec.Target = &v1alpha1.Target{
-			TargetSelector: exp.Target.NetworkChaos.TargetScope.parseSelector(),
+			TargetSelector: exp.Target.NetworkChaos.TargetScope.ParseSelector(),
 			TargetMode:     v1alpha1.PodMode(exp.Target.NetworkChaos.TargetScope.Mode),
 			TargetValue:    exp.Target.NetworkChaos.TargetScope.Value,
 		}
@@ -348,7 +354,7 @@ func (s *Service) createIOChaos(exp *ExperimentInfo) error {
 			Annotations: exp.Annotations,
 		},
 		Spec: v1alpha1.IoChaosSpec{
-			Selector: exp.Scope.parseSelector(),
+			Selector: exp.Scope.ParseSelector(),
 			Action:   v1alpha1.IOChaosAction(exp.Target.IOChaos.Action),
 			Mode:     v1alpha1.PodMode(exp.Scope.Mode),
 			Value:    exp.Scope.Value,
@@ -383,7 +389,7 @@ func (s *Service) createTimeChaos(exp *ExperimentInfo) error {
 			Annotations: exp.Annotations,
 		},
 		Spec: v1alpha1.TimeChaosSpec{
-			Selector:       exp.Scope.parseSelector(),
+			Selector:       exp.Scope.ParseSelector(),
 			Mode:           v1alpha1.PodMode(exp.Scope.Mode),
 			Value:          exp.Scope.Value,
 			TimeOffset:     exp.Target.TimeChaos.TimeOffset,
@@ -412,7 +418,7 @@ func (s *Service) createKernelChaos(exp *ExperimentInfo) error {
 			Annotations: exp.Annotations,
 		},
 		Spec: v1alpha1.KernelChaosSpec{
-			Selector:        exp.Scope.parseSelector(),
+			Selector:        exp.Scope.ParseSelector(),
 			Mode:            v1alpha1.PodMode(exp.Scope.Mode),
 			Value:           exp.Scope.Value,
 			FailKernRequest: exp.Target.KernelChaos.FailKernRequest,
@@ -439,7 +445,7 @@ func (s *Service) createStressChaos(exp *ExperimentInfo) error {
 			Annotations: exp.Annotations,
 		},
 		Spec: v1alpha1.StressChaosSpec{
-			Selector:          exp.Scope.parseSelector(),
+			Selector:          exp.Scope.ParseSelector(),
 			Mode:              v1alpha1.PodMode(exp.Scope.Mode),
 			Value:             exp.Scope.Value,
 			Stressors:         exp.Target.StressChaos.Stressors,
@@ -474,13 +480,15 @@ func (s *Service) getPodChaosDetail(namespace string, name string) (ExperimentIn
 		Labels:      chaos.Labels,
 		Annotations: chaos.Annotations,
 		Scope: ScopeInfo{
-			NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
-			LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
-			AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
-			FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
-			PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
-			Mode:                string(chaos.Spec.Mode),
-			Value:               chaos.Spec.Value,
+			SelectorInfo: SelectorInfo{
+				NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
+				LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
+				AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
+				FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
+				PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
+			},
+			Mode:  string(chaos.Spec.Mode),
+			Value: chaos.Spec.Value,
 		},
 		Scheduler: SchedulerInfo{
 			Cron: chaos.Spec.Scheduler.Cron,
@@ -514,13 +522,15 @@ func (s *Service) getIoChaosDetail(namespace string, name string) (ExperimentInf
 		Labels:      chaos.Labels,
 		Annotations: chaos.Annotations,
 		Scope: ScopeInfo{
-			NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
-			LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
-			AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
-			FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
-			PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
-			Mode:                string(chaos.Spec.Mode),
-			Value:               chaos.Spec.Value,
+			SelectorInfo: SelectorInfo{
+				NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
+				LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
+				AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
+				FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
+				PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
+			},
+			Mode:  string(chaos.Spec.Mode),
+			Value: chaos.Spec.Value,
 		},
 		Scheduler: SchedulerInfo{
 			Cron: chaos.Spec.Scheduler.Cron,
@@ -559,13 +569,15 @@ func (s *Service) getNetworkChaosDetail(namespace string, name string) (Experime
 		Labels:      chaos.Labels,
 		Annotations: chaos.Annotations,
 		Scope: ScopeInfo{
-			NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
-			LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
-			AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
-			FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
-			PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
-			Mode:                string(chaos.Spec.Mode),
-			Value:               chaos.Spec.Value,
+			SelectorInfo: SelectorInfo{
+				NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
+				LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
+				AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
+				FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
+				PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
+			},
+			Mode:  string(chaos.Spec.Mode),
+			Value: chaos.Spec.Value,
 		},
 		Scheduler: SchedulerInfo{
 			Cron: chaos.Spec.Scheduler.Cron,
@@ -580,13 +592,15 @@ func (s *Service) getNetworkChaosDetail(namespace string, name string) (Experime
 				Bandwidth: chaos.Spec.Bandwidth,
 				Direction: string(chaos.Spec.Direction),
 				TargetScope: &ScopeInfo{
-					NamespaceSelectors:  chaos.Spec.Target.TargetSelector.Namespaces,
-					LabelSelectors:      chaos.Spec.Target.TargetSelector.LabelSelectors,
-					AnnotationSelectors: chaos.Spec.Target.TargetSelector.AnnotationSelectors,
-					FieldSelectors:      chaos.Spec.Target.TargetSelector.FieldSelectors,
-					PhaseSelector:       chaos.Spec.Target.TargetSelector.PodPhaseSelectors,
-					Mode:                string(chaos.Spec.Target.TargetMode),
-					Value:               chaos.Spec.Target.TargetValue,
+					SelectorInfo: SelectorInfo{
+						NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
+						LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
+						AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
+						FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
+						PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
+					},
+					Mode:  string(chaos.Spec.Target.TargetMode),
+					Value: chaos.Spec.Target.TargetValue,
 				},
 			},
 		},
@@ -613,13 +627,15 @@ func (s *Service) getTimeChaosDetail(namespace string, name string) (ExperimentI
 		Labels:      chaos.Labels,
 		Annotations: chaos.Annotations,
 		Scope: ScopeInfo{
-			NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
-			LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
-			AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
-			FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
-			PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
-			Mode:                string(chaos.Spec.Mode),
-			Value:               chaos.Spec.Value,
+			SelectorInfo: SelectorInfo{
+				NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
+				LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
+				AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
+				FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
+				PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
+			},
+			Mode:  string(chaos.Spec.Mode),
+			Value: chaos.Spec.Value,
 		},
 		Scheduler: SchedulerInfo{
 			Cron: chaos.Spec.Scheduler.Cron,
@@ -654,13 +670,15 @@ func (s *Service) getKernelChaosDetail(namespace string, name string) (Experimen
 		Labels:      chaos.Labels,
 		Annotations: chaos.Annotations,
 		Scope: ScopeInfo{
-			NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
-			LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
-			AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
-			FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
-			PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
-			Mode:                string(chaos.Spec.Mode),
-			Value:               chaos.Spec.Value,
+			SelectorInfo: SelectorInfo{
+				NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
+				LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
+				AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
+				FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
+				PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
+			},
+			Mode:  string(chaos.Spec.Mode),
+			Value: chaos.Spec.Value,
 		},
 		Scheduler: SchedulerInfo{
 			Cron: chaos.Spec.Scheduler.Cron,
@@ -693,13 +711,15 @@ func (s *Service) getStressChaosDetail(namespace string, name string) (Experimen
 		Labels:      chaos.Labels,
 		Annotations: chaos.Annotations,
 		Scope: ScopeInfo{
-			NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
-			LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
-			AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
-			FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
-			PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
-			Mode:                string(chaos.Spec.Mode),
-			Value:               chaos.Spec.Value,
+			SelectorInfo: SelectorInfo{
+				NamespaceSelectors:  chaos.Spec.Selector.Namespaces,
+				LabelSelectors:      chaos.Spec.Selector.LabelSelectors,
+				AnnotationSelectors: chaos.Spec.Selector.AnnotationSelectors,
+				FieldSelectors:      chaos.Spec.Selector.FieldSelectors,
+				PhaseSelector:       chaos.Spec.Selector.PodPhaseSelectors,
+			},
+			Mode:  string(chaos.Spec.Mode),
+			Value: chaos.Spec.Value,
 		},
 		Scheduler: SchedulerInfo{
 			Cron: chaos.Spec.Scheduler.Cron,
diff --git a/pkg/apivalidator/base_validator.go b/pkg/apivalidator/base_validator.go
index e1d8d359..dff37bf3 100644
--- a/pkg/apivalidator/base_validator.go
+++ b/pkg/apivalidator/base_validator.go
@@ -39,17 +39,11 @@ func NameValid(fl validator.FieldLevel) bool {
 	return true
 }
 
-// PATTEN defines allowed characters for name, namespace.
-const PATTEN = "^[-.\\w]*$"
+var namePattern = regexp.MustCompile("^[-.\\w]*$")
 
-// checkName can be used to check whether the given name meets PATTEN.
+// checkName can be used to check resource names.
 func checkName(name string) bool {
-	patten, err := regexp.Compile(PATTEN)
-	if err != nil {
-		return false
-	}
-
-	return patten.MatchString(name)
+	return namePattern.MatchString(name)
 }
 
 // CronValid can be used to check whether the given cron valid.
diff --git a/pkg/apivalidator/scope_validator.go b/pkg/apivalidator/scope_validator.go
index d76c761c..8bc6fbe4 100644
--- a/pkg/apivalidator/scope_validator.go
+++ b/pkg/apivalidator/scope_validator.go
@@ -17,8 +17,8 @@ import (
 	"strconv"
 
 	"github.com/go-playground/validator/v10"
-
 	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/util/validation"
 )
 
 // NamespaceSelectorsValid can be used to check whether namespace selectors is valid.
@@ -53,7 +53,8 @@ func MapSelectorsValid(fl validator.FieldLevel) bool {
 	}
 
 	for k, v := range ms {
-		if !checkName(k) || !checkName(v) {
+		if len(validation.IsQualifiedName(k)) != 0 ||
+			len(validation.IsValidLabelValue(v)) != 0 {
 			return false
 		}
 	}
diff --git a/pkg/utils/selector.go b/pkg/utils/selector.go
index 332ad00d..27a9c86f 100644
--- a/pkg/utils/selector.go
+++ b/pkg/utils/selector.go
@@ -54,7 +54,7 @@ func SelectAndFilterPods(ctx context.Context, c client.Client, spec SelectSpec)
 	mode := spec.GetMode()
 	value := spec.GetValue()
 
-	pods, err := selectPods(ctx, c, selector)
+	pods, err := SelectPods(ctx, c, selector)
 	if err != nil {
 		return nil, err
 	}
@@ -72,10 +72,10 @@ func SelectAndFilterPods(ctx context.Context, c client.Client, spec SelectSpec)
 	return filteredPod, nil
 }
 
-// selectPods returns the list of pods that are available for pod chaos action.
+// SelectPods returns the list of pods that are available for pod chaos action.
 // It returns all pods that match the configured label, annotation and namespace selectors.
 // If pods are specifically specified by `selector.Pods`, it just returns the selector.Pods.
-func selectPods(ctx context.Context, c client.Client, selector v1alpha1.SelectorSpec) ([]v1.Pod, error) {
+func SelectPods(ctx context.Context, c client.Client, selector v1alpha1.SelectorSpec) ([]v1.Pod, error) {
 	var pods []v1.Pod
 
 	// pods are specifically specified
@@ -83,11 +83,10 @@ func selectPods(ctx context.Context, c client.Client, selector v1alpha1.Selector
 		for ns, names := range selector.Pods {
 			for _, name := range names {
 				var pod v1.Pod
-				err := c.Get(ctx, types.NamespacedName{
+				if err := c.Get(ctx, types.NamespacedName{
 					Namespace: ns,
 					Name:      name,
-				}, &pod)
-				if err != nil {
+				}, &pod); err != nil {
 					return nil, err
 				}
 
@@ -107,9 +106,7 @@ func selectPods(ctx context.Context, c client.Client, selector v1alpha1.Selector
 	if len(selector.FieldSelectors) > 0 {
 		listOptions.FieldSelector = fields.SelectorFromSet(selector.FieldSelectors)
 	}
-	err := c.List(ctx, &podList, &listOptions)
-
-	if err != nil {
+	if err := c.List(ctx, &podList, &listOptions); err != nil {
 		return nil, err
 	}
 


Test patch:
diff --git a/pkg/utils/selector_test.go b/pkg/utils/selector_test.go
index 7658912d..0707a7c6 100644
--- a/pkg/utils/selector_test.go
+++ b/pkg/utils/selector_test.go
@@ -86,7 +86,7 @@ func TestSelectPods(t *testing.T) {
 	}
 
 	for _, tc := range tcs {
-		filteredPods, err := selectPods(context.Background(), c, tc.selector)
+		filteredPods, err := SelectPods(context.Background(), c, tc.selector)
 		g.Expect(err).ShouldNot(HaveOccurred(), tc.name)
 		g.Expect(len(filteredPods)).To(Equal(len(tc.expectedPods)), tc.name)
 	}