Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: kill k8s pod with multi labels not work #174

Merged
merged 1 commit into from
Sep 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 34 additions & 14 deletions exec/model/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"github.com/chaosblade-io/chaosblade-spec-go/spec"
"github.com/sirupsen/logrus"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/selection"
pkglabels "k8s.io/apimachinery/pkg/labels"
)

func GetOneAvailableContainerIdFromPod(pod v1.Pod) (containerId, containerName, runtime string, err error) {
Expand All @@ -34,39 +36,57 @@ func GetOneAvailableContainerIdFromPod(pod v1.Pod) (containerId, containerName,
if containerStatus.State.Running == nil {
continue
}
runtime,containerId := TruncateContainerObjectMetaUid(containerStatus.ContainerID)
return containerId, containerStatus.Name, runtime,nil
runtime, containerId := TruncateContainerObjectMetaUid(containerStatus.ContainerID)
return containerId, containerStatus.Name, runtime, nil
}
return "", "", "", fmt.Errorf("cannot find a valiable container in %s pod", pod.Name)
}

func ParseLabels(labels string) map[string]string {
labelsMap := make(map[string]string, 0)
func ParseLabels(labels string) []pkglabels.Requirement {
labelArr := strings.Split(labels, ",")
requirements := make([]pkglabels.Requirement, 0, len(labelArr))
labelsMap := make(map[string][]string, 0)
if labels == "" {
return labelsMap
return requirements
}
labelArr := strings.Split(labels, ",")

for _, label := range labelArr {
keyValue := strings.SplitN(label, "=", 2)
if len(keyValue) != 2 {
logrus.Warningf("label %s is illegal", label)
continue
}
labelsMap[keyValue[0]] = keyValue[1]
if labelsMap[keyValue[0]] == nil {
valueArr := make([]string, 0)
valueArr = append(valueArr, keyValue[1])
labelsMap[keyValue[0]] = valueArr
} else {
labelsMap[keyValue[0]] = append(labelsMap[keyValue[0]], keyValue[1])
}
}

for label, value := range labelsMap {
requirement, err := pkglabels.NewRequirement(label, selection.In, value)
if err != nil {
logrus.Warningf("requirement %s-%s is illegal", label, value)
continue
}
requirements = append(requirements, *requirement)
}
return labelsMap
return requirements
}

func MapContains(bigMap map[string]string, subMap map[string]string) bool {
if bigMap == nil || subMap == nil {
func MapContains(bigMap map[string]string, requirements []pkglabels.Requirement) bool {
if bigMap == nil || requirements == nil {
return false
}
for k, v := range subMap {
if bigMap[k] != v {
return false
labelSet := pkglabels.Set(bigMap)
for i := 0; i < len(requirements); i++ {
if requirements[i].Matches(labelSet) {
return true
}
}
return true
return false
}

func CheckFlags(flags map[string]string) *spec.Response {
Expand Down
11 changes: 6 additions & 5 deletions exec/model/filter_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (b *BaseExperimentController) filterByOtherFlags(pods []v1.Pod, flags map[s
var resourceFunc = func(ctx context.Context, client2 *channel.Client, flags map[string]string) ([]v1.Pod, *spec.Response) {
namespace := flags[ResourceNamespaceFlag.Name]
labels := flags[ResourceLabelsFlag.Name]
labelsMap := ParseLabels(labels)
requirements := ParseLabels(labels)
logrusField := logrus.WithField("experiment", GetExperimentIdFromContext(ctx))
pods := make([]v1.Pod, 0)
names := flags[ResourceNamesFlag.Name]
Expand All @@ -124,7 +124,7 @@ var resourceFunc = func(ctx context.Context, client2 *channel.Client, flags map[
logrusField.Warningf("can not find the pod by %s name in %s namespace, %v", name, namespace, err)
continue
}
if MapContains(pod.Labels, labelsMap) {
if MapContains(pod.Labels, requirements) {
pods = append(pods, pod)
}
}
Expand All @@ -134,14 +134,15 @@ var resourceFunc = func(ctx context.Context, client2 *channel.Client, flags map[
}
return pods, spec.Success()
}
if labels != "" && len(labelsMap) == 0 {
if labels != "" && len(requirements) == 0 {
msg := spec.ParameterIllegal.Sprintf(ResourceLabelsFlag.Name, labels, "data format error")
logrusField.Warningln(msg)
return pods, spec.ResponseFailWithFlags(spec.ParameterLess, ResourceLabelsFlag.Name, labels, "data format error, example: key=value")
}
if len(labelsMap) > 0 {
if len(requirements) > 0 {
podList := v1.PodList{}
opts := client.ListOptions{Namespace: namespace, LabelSelector: pkglabels.SelectorFromSet(labelsMap)}
selector := pkglabels.NewSelector().Add(requirements...)
opts := client.ListOptions{Namespace: namespace, LabelSelector: selector}
err := client2.List(context.TODO(), &podList, &opts)
if err != nil {
return pods, spec.ResponseFailWithFlags(spec.K8sExecFailed, "PodList", err)
Expand Down
11 changes: 6 additions & 5 deletions exec/node/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (e *ExpController) filterByOtherFlags(nodes []v1.Node, flags map[string]str

var resourceFunc = func(ctx context.Context, client2 *channel.Client, flags map[string]string) ([]v1.Node, *spec.Response) {
labels := flags[model.ResourceLabelsFlag.Name]
labelsMap := model.ParseLabels(labels)
requirements := model.ParseLabels(labels)
logrusField := logrus.WithField("experiment", model.GetExperimentIdFromContext(ctx))
nodes := make([]v1.Node, 0)
names := flags[model.ResourceNamesFlag.Name]
Expand All @@ -88,7 +88,7 @@ var resourceFunc = func(ctx context.Context, client2 *channel.Client, flags map[
logrusField.Warningf("can not find the node by %s name, %v", name, err)
continue
}
if model.MapContains(node.Labels, labelsMap) {
if model.MapContains(node.Labels, requirements) {
nodes = append(nodes, node)
}
}
Expand All @@ -98,13 +98,14 @@ var resourceFunc = func(ctx context.Context, client2 *channel.Client, flags map[
}
return nodes, spec.Success()
}
if labels != "" && len(labelsMap) == 0 {
if labels != "" && len(requirements) == 0 {
logrusField.Warningln(spec.ParameterIllegal.Sprintf(model.ResourceLabelsFlag.Name, labels, "illegal labels"))
return nodes, spec.ResponseFailWithFlags(spec.ParameterIllegal, model.ResourceLabelsFlag.Name, labels, "illegal labels")
}
if len(labelsMap) > 0 {
if len(requirements) > 0 {
nodeList := v1.NodeList{}
opts := client.ListOptions{LabelSelector: pkglabels.SelectorFromSet(labelsMap)}
selector := pkglabels.NewSelector().Add(requirements...)
opts := client.ListOptions{LabelSelector: selector}
err := client2.List(context.TODO(), &nodeList, &opts)
if err != nil {
return nodes, spec.ResponseFailWithFlags(spec.K8sExecFailed, "ListNode", err)
Expand Down