From 433e40d2fb8535b67e926786a76002a461107a40 Mon Sep 17 00:00:00 2001 From: Udit Gaurav <35391335+uditgaurav@users.noreply.github.com> Date: Wed, 16 Mar 2022 16:06:10 +0530 Subject: [PATCH] (enahncement)experiment: add node label filter for pod network and stress chaos (#494) Signed-off-by: uditgaurav --- .../container-kill/lib/container-kill.go | 26 +++++- chaoslib/litmus/disk-fill/lib/disk-fill.go | 28 ++++-- .../litmus/network-chaos/lib/network-chaos.go | 29 +++++- chaoslib/litmus/pod-delete/lib/pod-delete.go | 53 +++++++++-- .../litmus/stress-chaos/lib/stress-chaos.go | 26 +++++- .../container-kill/environment/environment.go | 1 + pkg/generic/container-kill/types/types.go | 1 + .../disk-fill/environment/environment.go | 2 + pkg/generic/disk-fill/types/types.go | 1 + .../network-chaos/environment/environment.go | 1 + pkg/generic/network-chaos/types/types.go | 1 + .../pod-delete/environment/environment.go | 1 + pkg/generic/pod-delete/types/types.go | 1 + .../stress-chaos/environment/environment.go | 1 + pkg/generic/stress-chaos/types/types.go | 1 + pkg/utils/common/pods.go | 91 +++++++++++++++++++ 16 files changed, 238 insertions(+), 26 deletions(-) diff --git a/chaoslib/litmus/container-kill/lib/container-kill.go b/chaoslib/litmus/container-kill/lib/container-kill.go index 8f64a5204..ffa4f4c8e 100644 --- a/chaoslib/litmus/container-kill/lib/container-kill.go +++ b/chaoslib/litmus/container-kill/lib/container-kill.go @@ -20,6 +20,9 @@ import ( //PrepareContainerKill contains the prepration steps before chaos injection func PrepareContainerKill(experimentsDetails *experimentTypes.ExperimentDetails, clients clients.ClientSets, resultDetails *types.ResultDetails, eventsDetails *types.EventDetails, chaosDetails *types.ChaosDetails) error { + targetPodList := apiv1.PodList{} + var err error + var podsAffectedPerc int // Get the target pod details for the chaos execution // if the target pod is not defined it will derive the random target pod list using pod affected percentage if experimentsDetails.TargetPods == "" && chaosDetails.AppDetail.Label == "" { @@ -33,10 +36,25 @@ func PrepareContainerKill(experimentsDetails *experimentTypes.ExperimentDetails, "Sequence": experimentsDetails.Sequence, }) - podsAffectedPerc, _ := strconv.Atoi(experimentsDetails.PodsAffectedPerc) - targetPodList, err := common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) - if err != nil { - return err + podsAffectedPerc, _ = strconv.Atoi(experimentsDetails.PodsAffectedPerc) + if experimentsDetails.NodeLabel == "" { + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } else { + if experimentsDetails.TargetPods == "" { + targetPodList, err = common.GetPodListFromSpecifiedNodes(experimentsDetails.TargetPods, podsAffectedPerc, experimentsDetails.NodeLabel, clients, chaosDetails) + if err != nil { + return err + } + } else { + log.Infof("TARGET_PODS env is provided, overriding the NODE_LABEL input") + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } } podNames := []string{} diff --git a/chaoslib/litmus/disk-fill/lib/disk-fill.go b/chaoslib/litmus/disk-fill/lib/disk-fill.go index 2644a142e..d4a6c60d4 100644 --- a/chaoslib/litmus/disk-fill/lib/disk-fill.go +++ b/chaoslib/litmus/disk-fill/lib/disk-fill.go @@ -21,15 +21,16 @@ import ( //PrepareDiskFill contains the prepration steps before chaos injection func PrepareDiskFill(experimentsDetails *experimentTypes.ExperimentDetails, clients clients.ClientSets, resultDetails *types.ResultDetails, eventsDetails *types.EventDetails, chaosDetails *types.ChaosDetails) error { + targetPodList := apiv1.PodList{} + var err error + var podsAffectedPerc int // It will contains all the pod & container details required for exec command execCommandDetails := exec.PodDetails{} - // Get the target pod details for the chaos execution // if the target pod is not defined it will derive the random target pod list using pod affected percentage if experimentsDetails.TargetPods == "" && chaosDetails.AppDetail.Label == "" { return errors.Errorf("please provide one of the appLabel or TARGET_PODS") } - //setup the tunables if provided in range setChaosTunables(experimentsDetails) @@ -40,10 +41,25 @@ func PrepareDiskFill(experimentsDetails *experimentTypes.ExperimentDetails, clie "Sequence": experimentsDetails.Sequence, }) - podsAffectedPerc, _ := strconv.Atoi(experimentsDetails.PodsAffectedPerc) - targetPodList, err := common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) - if err != nil { - return err + podsAffectedPerc, _ = strconv.Atoi(experimentsDetails.PodsAffectedPerc) + if experimentsDetails.NodeLabel == "" { + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } else { + if experimentsDetails.TargetPods == "" { + targetPodList, err = common.GetPodListFromSpecifiedNodes(experimentsDetails.TargetPods, podsAffectedPerc, experimentsDetails.NodeLabel, clients, chaosDetails) + if err != nil { + return err + } + } else { + log.Infof("TARGET_PODS env is provided, overriding the NODE_LABEL input") + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } } podNames := []string{} diff --git a/chaoslib/litmus/network-chaos/lib/network-chaos.go b/chaoslib/litmus/network-chaos/lib/network-chaos.go index cd6d8ae7f..028b9452d 100644 --- a/chaoslib/litmus/network-chaos/lib/network-chaos.go +++ b/chaoslib/litmus/network-chaos/lib/network-chaos.go @@ -21,6 +21,9 @@ import ( //PrepareAndInjectChaos contains the prepration & injection steps func PrepareAndInjectChaos(experimentsDetails *experimentTypes.ExperimentDetails, clients clients.ClientSets, resultDetails *types.ResultDetails, eventsDetails *types.EventDetails, chaosDetails *types.ChaosDetails, args string) error { + targetPodList := apiv1.PodList{} + var err error + var podsAffectedPerc int // Get the target pod details for the chaos execution // if the target pod is not defined it will derive the random target pod list using pod affected percentage if experimentsDetails.TargetPods == "" && chaosDetails.AppDetail.Label == "" { @@ -55,10 +58,28 @@ func PrepareAndInjectChaos(experimentsDetails *experimentTypes.ExperimentDetails "PodsAffectedPerc": experimentsDetails.PodsAffectedPerc, }) } - podsAffectedPerc, _ := strconv.Atoi(experimentsDetails.PodsAffectedPerc) - targetPodList, err := common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) - if err != nil { - return err + podsAffectedPerc, _ = strconv.Atoi(experimentsDetails.PodsAffectedPerc) + if experimentsDetails.NodeLabel == "" { + + //targetPodList, err := common.GetPodListFromSpecifiedNodes(experimentsDetails.TargetPods, experimentsDetails.PodsAffectedPerc, clients, chaosDetails) + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } else { + //targetPodList, err := common.GetPodList(experimentsDetails.TargetPods, experimentsDetails.PodsAffectedPerc, clients, chaosDetails) + if experimentsDetails.TargetPods == "" { + targetPodList, err = common.GetPodListFromSpecifiedNodes(experimentsDetails.TargetPods, podsAffectedPerc, experimentsDetails.NodeLabel, clients, chaosDetails) + if err != nil { + return err + } + } else { + log.Infof("TARGET_PODS env is provided, overriding the NODE_LABEL input") + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } } podNames := []string{} diff --git a/chaoslib/litmus/pod-delete/lib/pod-delete.go b/chaoslib/litmus/pod-delete/lib/pod-delete.go index 71071a461..d25308072 100644 --- a/chaoslib/litmus/pod-delete/lib/pod-delete.go +++ b/chaoslib/litmus/pod-delete/lib/pod-delete.go @@ -16,6 +16,7 @@ import ( "github.com/litmuschaos/litmus-go/pkg/utils/common" "github.com/pkg/errors" "github.com/sirupsen/logrus" + apiv1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -60,6 +61,9 @@ func PreparePodDelete(experimentsDetails *experimentTypes.ExperimentDetails, cli // injectChaosInSerialMode delete the target application pods serial mode(one by one) func injectChaosInSerialMode(experimentsDetails *experimentTypes.ExperimentDetails, clients clients.ClientSets, chaosDetails *types.ChaosDetails, eventsDetails *types.EventDetails, resultDetails *types.ResultDetails) error { + targetPodList := apiv1.PodList{} + var err error + var podsAffectedPerc int // run the probes during chaos if len(resultDetails.ProbeDetails) != 0 { if err := probe.RunProbes(chaosDetails, clients, resultDetails, "DuringChaos", eventsDetails); err != nil { @@ -78,10 +82,25 @@ func injectChaosInSerialMode(experimentsDetails *experimentTypes.ExperimentDetai if experimentsDetails.TargetPods == "" && chaosDetails.AppDetail.Label == "" { return errors.Errorf("please provide one of the appLabel or TARGET_PODS") } - podsAffectedPerc, _ := strconv.Atoi(experimentsDetails.PodsAffectedPerc) - targetPodList, err := common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) - if err != nil { - return err + podsAffectedPerc, _ = strconv.Atoi(experimentsDetails.PodsAffectedPerc) + if experimentsDetails.NodeLabel == "" { + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } else { + if experimentsDetails.TargetPods == "" { + targetPodList, err = common.GetPodListFromSpecifiedNodes(experimentsDetails.TargetPods, podsAffectedPerc, experimentsDetails.NodeLabel, clients, chaosDetails) + if err != nil { + return err + } + } else { + log.Infof("TARGET_PODS env is provided, overriding the NODE_LABEL input") + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } } // deriving the parent name of the target resources @@ -158,6 +177,9 @@ func injectChaosInSerialMode(experimentsDetails *experimentTypes.ExperimentDetai // injectChaosInParallelMode delete the target application pods in parallel mode (all at once) func injectChaosInParallelMode(experimentsDetails *experimentTypes.ExperimentDetails, clients clients.ClientSets, chaosDetails *types.ChaosDetails, eventsDetails *types.EventDetails, resultDetails *types.ResultDetails) error { + targetPodList := apiv1.PodList{} + var err error + var podsAffectedPerc int // run the probes during chaos if len(resultDetails.ProbeDetails) != 0 { if err := probe.RunProbes(chaosDetails, clients, resultDetails, "DuringChaos", eventsDetails); err != nil { @@ -176,10 +198,25 @@ func injectChaosInParallelMode(experimentsDetails *experimentTypes.ExperimentDet if experimentsDetails.TargetPods == "" && chaosDetails.AppDetail.Label == "" { return errors.Errorf("please provide one of the appLabel or TARGET_PODS") } - podsAffectedPerc, _ := strconv.Atoi(experimentsDetails.PodsAffectedPerc) - targetPodList, err := common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) - if err != nil { - return err + podsAffectedPerc, _ = strconv.Atoi(experimentsDetails.PodsAffectedPerc) + if experimentsDetails.NodeLabel == "" { + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } else { + if experimentsDetails.TargetPods == "" { + targetPodList, err = common.GetPodListFromSpecifiedNodes(experimentsDetails.TargetPods, podsAffectedPerc, experimentsDetails.NodeLabel, clients, chaosDetails) + if err != nil { + return err + } + } else { + log.Infof("TARGET_PODS env is provided, overriding the NODE_LABEL input") + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } } // deriving the parent name of the target resources diff --git a/chaoslib/litmus/stress-chaos/lib/stress-chaos.go b/chaoslib/litmus/stress-chaos/lib/stress-chaos.go index b31d2c3f1..2ae810c25 100644 --- a/chaoslib/litmus/stress-chaos/lib/stress-chaos.go +++ b/chaoslib/litmus/stress-chaos/lib/stress-chaos.go @@ -20,6 +20,9 @@ import ( //PrepareAndInjectStressChaos contains the prepration & injection steps for the stress experiments. func PrepareAndInjectStressChaos(experimentsDetails *experimentTypes.ExperimentDetails, clients clients.ClientSets, resultDetails *types.ResultDetails, eventsDetails *types.EventDetails, chaosDetails *types.ChaosDetails) error { + targetPodList := apiv1.PodList{} + var err error + var podsAffectedPerc int //Setup the tunables if provided in range SetChaosTunables(experimentsDetails) @@ -55,10 +58,25 @@ func PrepareAndInjectStressChaos(experimentsDetails *experimentTypes.ExperimentD if experimentsDetails.TargetPods == "" && chaosDetails.AppDetail.Label == "" { return errors.Errorf("Please provide one of the appLabel or TARGET_PODS") } - PodsAffectedPerc, _ := strconv.Atoi(experimentsDetails.PodsAffectedPerc) - targetPodList, err := common.GetPodList(experimentsDetails.TargetPods, PodsAffectedPerc, clients, chaosDetails) - if err != nil { - return err + podsAffectedPerc, _ = strconv.Atoi(experimentsDetails.PodsAffectedPerc) + if experimentsDetails.NodeLabel == "" { + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } else { + if experimentsDetails.TargetPods == "" { + targetPodList, err = common.GetPodListFromSpecifiedNodes(experimentsDetails.TargetPods, podsAffectedPerc, experimentsDetails.NodeLabel, clients, chaosDetails) + if err != nil { + return err + } + } else { + log.Infof("TARGET_PODS env is provided, overriding the NODE_LABEL input") + targetPodList, err = common.GetPodList(experimentsDetails.TargetPods, podsAffectedPerc, clients, chaosDetails) + if err != nil { + return err + } + } } podNames := []string{} diff --git a/pkg/generic/container-kill/environment/environment.go b/pkg/generic/container-kill/environment/environment.go index d58ff4e0c..36ca57c88 100644 --- a/pkg/generic/container-kill/environment/environment.go +++ b/pkg/generic/container-kill/environment/environment.go @@ -37,4 +37,5 @@ func GetENV(experimentDetails *experimentTypes.ExperimentDetails) { experimentDetails.Sequence = types.Getenv("SEQUENCE", "parallel") experimentDetails.Signal = types.Getenv("SIGNAL", "SIGKILL") experimentDetails.TerminationGracePeriodSeconds, _ = strconv.Atoi(types.Getenv("TERMINATION_GRACE_PERIOD_SECONDS", "")) + experimentDetails.NodeLabel = types.Getenv("NODE_LABEL", "") } diff --git a/pkg/generic/container-kill/types/types.go b/pkg/generic/container-kill/types/types.go index 35367f146..c2c82f240 100644 --- a/pkg/generic/container-kill/types/types.go +++ b/pkg/generic/container-kill/types/types.go @@ -33,4 +33,5 @@ type ExperimentDetails struct { PodsAffectedPerc string Sequence string Signal string + NodeLabel string } diff --git a/pkg/generic/disk-fill/environment/environment.go b/pkg/generic/disk-fill/environment/environment.go index 938ed6817..268ae4570 100644 --- a/pkg/generic/disk-fill/environment/environment.go +++ b/pkg/generic/disk-fill/environment/environment.go @@ -37,4 +37,6 @@ func GetENV(experimentDetails *experimentTypes.ExperimentDetails) { experimentDetails.EphemeralStorageMebibytes = types.Getenv("EPHEMERAL_STORAGE_MEBIBYTES", "") experimentDetails.TerminationGracePeriodSeconds, _ = strconv.Atoi(types.Getenv("TERMINATION_GRACE_PERIOD_SECONDS", "")) experimentDetails.DataBlockSize, _ = strconv.Atoi(types.Getenv("DATA_BLOCK_SIZE", "256")) + experimentDetails.NodeLabel = types.Getenv("NODE_LABEL", "") + } diff --git a/pkg/generic/disk-fill/types/types.go b/pkg/generic/disk-fill/types/types.go index a4a652f1d..e674eb768 100644 --- a/pkg/generic/disk-fill/types/types.go +++ b/pkg/generic/disk-fill/types/types.go @@ -34,4 +34,5 @@ type ExperimentDetails struct { EphemeralStorageMebibytes string TerminationGracePeriodSeconds int DataBlockSize int + NodeLabel string } diff --git a/pkg/generic/network-chaos/environment/environment.go b/pkg/generic/network-chaos/environment/environment.go index 2226c3e79..91ddcc098 100644 --- a/pkg/generic/network-chaos/environment/environment.go +++ b/pkg/generic/network-chaos/environment/environment.go @@ -31,6 +31,7 @@ func GetENV(experimentDetails *experimentTypes.ExperimentDetails, expName string experimentDetails.Timeout, _ = strconv.Atoi(types.Getenv("STATUS_CHECK_TIMEOUT", "180")) experimentDetails.TargetPods = types.Getenv("TARGET_PODS", "") experimentDetails.PodsAffectedPerc = types.Getenv("PODS_AFFECTED_PERC", "0") + experimentDetails.NodeLabel = types.Getenv("NODE_LABEL", "") experimentDetails.DestinationIPs = types.Getenv("DESTINATION_IPS", "") experimentDetails.DestinationHosts = types.Getenv("DESTINATION_HOSTS", "") experimentDetails.ContainerRuntime = types.Getenv("CONTAINER_RUNTIME", "docker") diff --git a/pkg/generic/network-chaos/types/types.go b/pkg/generic/network-chaos/types/types.go index 98d2b702b..8c44c37ef 100644 --- a/pkg/generic/network-chaos/types/types.go +++ b/pkg/generic/network-chaos/types/types.go @@ -41,4 +41,5 @@ type ExperimentDetails struct { TerminationGracePeriodSeconds int Jitter int NetworkChaosType string + NodeLabel string } diff --git a/pkg/generic/pod-delete/environment/environment.go b/pkg/generic/pod-delete/environment/environment.go index 677c83375..d5fc59f8c 100644 --- a/pkg/generic/pod-delete/environment/environment.go +++ b/pkg/generic/pod-delete/environment/environment.go @@ -32,4 +32,5 @@ func GetENV(experimentDetails *experimentTypes.ExperimentDetails) { experimentDetails.TargetPods = types.Getenv("TARGET_PODS", "") experimentDetails.Sequence = types.Getenv("SEQUENCE", "parallel") experimentDetails.TargetContainer = types.Getenv("TARGET_CONTAINER", "") + experimentDetails.NodeLabel = types.Getenv("NODE_LABEL", "") } diff --git a/pkg/generic/pod-delete/types/types.go b/pkg/generic/pod-delete/types/types.go index 98f8401a9..aa6cddc5f 100644 --- a/pkg/generic/pod-delete/types/types.go +++ b/pkg/generic/pod-delete/types/types.go @@ -28,4 +28,5 @@ type ExperimentDetails struct { Sequence string LIBImagePullPolicy string TargetContainer string + NodeLabel string } diff --git a/pkg/generic/stress-chaos/environment/environment.go b/pkg/generic/stress-chaos/environment/environment.go index fd5ac9aaa..fb0ebe7bd 100644 --- a/pkg/generic/stress-chaos/environment/environment.go +++ b/pkg/generic/stress-chaos/environment/environment.go @@ -35,6 +35,7 @@ func GetENV(experimentDetails *experimentTypes.ExperimentDetails, expName string experimentDetails.Sequence = types.Getenv("SEQUENCE", "parallel") experimentDetails.TerminationGracePeriodSeconds, _ = strconv.Atoi(types.Getenv("TERMINATION_GRACE_PERIOD_SECONDS", "")) experimentDetails.StressImage = types.Getenv("STRESS_IMAGE", "alexeiled/stress-ng:latest-ubuntu") + experimentDetails.NodeLabel = types.Getenv("NODE_LABEL", "") switch expName { case "pod-cpu-hog": diff --git a/pkg/generic/stress-chaos/types/types.go b/pkg/generic/stress-chaos/types/types.go index 8d2484ddc..369020489 100644 --- a/pkg/generic/stress-chaos/types/types.go +++ b/pkg/generic/stress-chaos/types/types.go @@ -40,4 +40,5 @@ type ExperimentDetails struct { MemoryConsumption string VolumeMountPath string StressType string + NodeLabel string } diff --git a/pkg/utils/common/pods.go b/pkg/utils/common/pods.go index c7aef0f29..f8fe9978f 100644 --- a/pkg/utils/common/pods.go +++ b/pkg/utils/common/pods.go @@ -390,3 +390,94 @@ func CheckContainerStatus(appNamespace, appName string, clients clients.ClientSe return nil }) } + +// GetPodListFromSpecifiedNodes will filter out the pod list scheduled on specified node +func GetPodListFromSpecifiedNodes(targetPods string, podAffPerc int, nodeLabel string, clients clients.ClientSets, chaosDetails *types.ChaosDetails) (core_v1.PodList, error) { + finalPods := core_v1.PodList{} + var nodes *core_v1.NodeList + /* + isPodsAvailable, err := VerifyExistanceOfPods(chaosDetails.AppDetail.Namespace, targetPods, clients) + if err != nil { + return core_v1.PodList{}, err + }*/ + + // identify node list from the provided node label + nodes, err = clients.KubeClient.CoreV1().Nodes().List(v1.ListOptions{LabelSelector: nodeLabel}) + if err != nil { + return core_v1.PodList{}, errors.Errorf("Failed to find the nodes with matching label, err: %v", err) + } else if len(nodes.Items) == 0 { + return core_v1.PodList{}, errors.Errorf("Failed to find the nodes with matching label") + } + nodeNames := []string{} + for _, node := range nodes.Items { + nodeNames = append(nodeNames, node.Name) + } + + log.Infof("[Chaos]:Looking for pods with specified attributes on nodes targeted: %v", nodeNames) + + nonChaosPods, err := FilterNonChaosPods(clients, chaosDetails) + if err != nil { + return core_v1.PodList{}, err + } + podList, err := getTargetPodsWhenNodeFilterSet(podAffPerc, clients, nonChaosPods, nodeNames, chaosDetails) + if err != nil { + return core_v1.PodList{}, err + } + + finalPods.Items = append(finalPods.Items, podList.Items...) + + log.Infof("[Chaos]:Number of pods targeted: %v", len(finalPods.Items)) + return finalPods, nil +} + +// getTargetPodsWhenNodeFilterSet will give the target pod when the node filter is setup +func getTargetPodsWhenNodeFilterSet(podAffPerc int, clients clients.ClientSets, nonChaosPods core_v1.PodList, nodes []string, chaosDetails *types.ChaosDetails) (core_v1.PodList, error) { + filteredPods := core_v1.PodList{} + nodeFilteredPods := core_v1.PodList{} + realPods := core_v1.PodList{} + for _, pod := range nonChaosPods.Items { + switch chaosDetails.AppDetail.AnnotationCheck { + case true: + parentName, err := annotation.GetParentName(clients, pod, chaosDetails) + if err != nil { + return core_v1.PodList{}, err + } + isParentAnnotated, err := annotation.IsParentAnnotated(clients, parentName, chaosDetails) + if err != nil { + return core_v1.PodList{}, err + } + if isParentAnnotated { + filteredPods.Items = append(filteredPods.Items, pod) + } + default: + filteredPods.Items = append(filteredPods.Items, pod) + } + } + + // add filter for pods which are on derived node list + for _, pod := range filteredPods.Items { + for _, itemIndex := range nodes { + if pod.Spec.NodeName == itemIndex { + nodeFilteredPods.Items = append(nodeFilteredPods.Items, pod) + break // a given pod obj is found in only one node, break and start checking next pod + } + + } + } + + if len(nodeFilteredPods.Items) == 0 { + return filteredPods, errors.Errorf("No pod found with desired attributes on specified node(s)") + } + + newPodListLength := math.Maximum(1, math.Adjustment(math.Minimum(podAffPerc, 100), len(nodeFilteredPods.Items))) + rand.Seed(time.Now().UnixNano()) + + // it will generate the random podlist + // it starts from the random index and choose requirement no of pods next to that index in a circular way. + index := rand.Intn(len(nodeFilteredPods.Items)) + for i := 0; i < newPodListLength; i++ { + realPods.Items = append(realPods.Items, nodeFilteredPods.Items[index]) + index = (index + 1) % len(nodeFilteredPods.Items) + } + return realPods, nil +}