pods.go 6.1 KB
Newer Older
J
jeff 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*

 Copyright 2019 The KubeSphere Authors.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

*/
package resources

import (
Z
zryfish 已提交
21
	v12 "k8s.io/api/apps/v1"
H
hongming 已提交
22 23
	"kubesphere.io/kubesphere/pkg/informers"
	"kubesphere.io/kubesphere/pkg/params"
J
jeff 已提交
24 25 26 27 28 29 30 31 32 33
	"sort"
	"strings"

	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/labels"
)

type podSearcher struct {
}

H
hongming 已提交
34 35 36
func (*podSearcher) get(namespace, name string) (interface{}, error) {
	return informers.SharedInformerFactory().Core().V1().Pods().Lister().Pods(namespace).Get(name)
}
Z
zryfish 已提交
37

H
hongming 已提交
38 39 40
func podBelongTo(item *v1.Pod, kind string, name string) bool {
	switch kind {
	case "Deployment":
Z
zryfish 已提交
41 42 43
		if podBelongToDeployment(item, name) {
			return true
		}
H
hongming 已提交
44
	case "ReplicaSet":
Z
zryfish 已提交
45 46 47
		if podBelongToReplicaSet(item, name) {
			return true
		}
H
hongming 已提交
48
	case "DaemonSet":
Z
zryfish 已提交
49 50 51
		if podBelongToDaemonSet(item, name) {
			return true
		}
H
hongming 已提交
52
	case "StatefulSet":
Z
zryfish 已提交
53 54 55
		if podBelongToStatefulSet(item, name) {
			return true
		}
H
hongming 已提交
56
	case "Job":
Z
zryfish 已提交
57 58 59 60 61 62 63
		if podBelongToJob(item, name) {
			return true
		}
	}
	return false
}

H
hongming 已提交
64
func replicaSetBelongToDeployment(replicaSet *v12.ReplicaSet, deploymentName string) bool {
Z
zryfish 已提交
65
	for _, owner := range replicaSet.OwnerReferences {
H
hongming 已提交
66
		if owner.Kind == "Deployment" && owner.Name == deploymentName {
Z
zryfish 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
			return true
		}
	}
	return false
}

func podBelongToDaemonSet(item *v1.Pod, name string) bool {
	for _, owner := range item.OwnerReferences {
		if owner.Kind == "DaemonSet" && owner.Name == name {
			return true
		}
	}
	return false
}

func podBelongToJob(item *v1.Pod, name string) bool {
	for _, owner := range item.OwnerReferences {
		if owner.Kind == "Job" && owner.Name == name {
			return true
		}
	}
	return false
}

H
hongming 已提交
91
func podBelongToReplicaSet(item *v1.Pod, replicaSetName string) bool {
Z
zryfish 已提交
92
	for _, owner := range item.OwnerReferences {
H
hongming 已提交
93
		if owner.Kind == "ReplicaSet" && owner.Name == replicaSetName {
Z
zryfish 已提交
94 95 96 97 98 99
			return true
		}
	}
	return false
}

H
hongming 已提交
100 101 102 103
func podBelongToStatefulSet(item *v1.Pod, statefulSetName string) bool {
	for _, owner := range item.OwnerReferences {
		if owner.Kind == "StatefulSet" && owner.Name == statefulSetName {
			return true
Z
zryfish 已提交
104 105 106 107 108
		}
	}
	return false
}

H
hongming 已提交
109
func podBelongToDeployment(item *v1.Pod, deploymentName string) bool {
Z
zryfish 已提交
110 111 112 113
	replicas, err := informers.SharedInformerFactory().Apps().V1().ReplicaSets().Lister().ReplicaSets(item.Namespace).List(labels.Everything())
	if err != nil {
		return false
	}
H
hongming 已提交
114

Z
zryfish 已提交
115
	for _, r := range replicas {
H
hongming 已提交
116 117
		if replicaSetBelongToDeployment(r, deploymentName) && podBelongToReplicaSet(item, r.Name) {
			return true
Z
zryfish 已提交
118 119
		}
	}
H
hongming 已提交
120

Z
zryfish 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
	return false
}

func podBindPVC(item *v1.Pod, pvcName string) bool {
	for _, v := range item.Spec.Volumes {
		if v.VolumeSource.PersistentVolumeClaim != nil &&
			v.VolumeSource.PersistentVolumeClaim.ClaimName == pvcName {
			return true
		}
	}
	return false
}

func podBelongToService(item *v1.Pod, serviceName string) bool {
	service, err := informers.SharedInformerFactory().Core().V1().Services().Lister().Services(item.Namespace).Get(serviceName)
	if err != nil {
		return false
	}
H
hongming 已提交
139 140 141 142

	selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
	if !selector.Matches(labels.Set(item.Labels)) {
		return false
Z
zryfish 已提交
143 144 145 146
	}
	return true
}

H
hongming 已提交
147
// exactly Match
J
jeff 已提交
148 149 150
func (*podSearcher) match(match map[string]string, item *v1.Pod) bool {
	for k, v := range match {
		switch k {
H
hongming 已提交
151
		case ownerKind:
Z
zryfish 已提交
152
			fallthrough
H
hongming 已提交
153 154 155
		case ownerName:
			kind := match[ownerKind]
			name := match[ownerName]
Z
zryfish 已提交
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
			if !podBelongTo(item, kind, name) {
				return false
			}
		case "nodeName":
			if item.Spec.NodeName != v {
				return false
			}
		case "pvcName":
			if !podBindPVC(item, v) {
				return false
			}
		case "serviceName":
			if !podBelongToService(item, v) {
				return false
			}
J
jeff 已提交
171 172 173 174
		case name:
			if item.Name != v && item.Labels[displayName] != v {
				return false
			}
H
hongming 已提交
175 176 177 178
		case keyword:
			if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
				return false
			}
J
jeff 已提交
179
		default:
Z
zryfish 已提交
180 181 182
			if item.Labels[k] != v {
				return false
			}
J
jeff 已提交
183 184 185 186 187
		}
	}
	return true
}

H
hongming 已提交
188
// Fuzzy searchInNamespace
J
jeff 已提交
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
func (*podSearcher) fuzzy(fuzzy map[string]string, item *v1.Pod) bool {
	for k, v := range fuzzy {
		switch k {
		case name:
			if !strings.Contains(item.Name, v) && !strings.Contains(item.Labels[displayName], v) {
				return false
			}
		case label:
			if !searchFuzzy(item.Labels, "", v) {
				return false
			}
		case annotation:
			if !searchFuzzy(item.Annotations, "", v) {
				return false
			}
			return false
		case app:
			if !strings.Contains(item.Labels[chart], v) && !strings.Contains(item.Labels[release], v) {
				return false
			}
		default:
			if !searchFuzzy(item.Labels, k, v) && !searchFuzzy(item.Annotations, k, v) {
				return false
			}
		}
	}
	return true
}

func (*podSearcher) compare(a, b *v1.Pod, orderBy string) bool {
	switch orderBy {
H
hongming 已提交
220
	case CreateTime:
H
hongming 已提交
221
		return a.CreationTimestamp.Time.Before(b.CreationTimestamp.Time)
J
jeff 已提交
222 223 224 225 226 227 228
	case name:
		fallthrough
	default:
		return strings.Compare(a.Name, b.Name) <= 0
	}
}

H
hongming 已提交
229
func (s *podSearcher) search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
J
jeff 已提交
230

H
hongming 已提交
231
	pods, err := informers.SharedInformerFactory().Core().V1().Pods().Lister().Pods(namespace).List(labels.Everything())
J
jeff 已提交
232 233 234 235 236 237 238

	if err != nil {
		return nil, err
	}

	result := make([]*v1.Pod, 0)

H
hongming 已提交
239
	if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
J
jeff 已提交
240 241 242
		result = pods
	} else {
		for _, item := range pods {
H
hongming 已提交
243
			if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
J
jeff 已提交
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
				result = append(result, item)
			}
		}
	}
	sort.Slice(result, func(i, j int) bool {
		if reverse {
			tmp := i
			i = j
			j = tmp
		}
		return s.compare(result[i], result[j], orderBy)
	})

	r := make([]interface{}, 0)
	for _, i := range result {
		r = append(r, i)
	}
	return r, nil
}