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

 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.

*/
Z
zryfish 已提交
18
package pod
J
jeff 已提交
19 20

import (
H
hongming 已提交
21
	appsv1 "k8s.io/api/apps/v1"
Z
zryfish 已提交
22 23 24
	"k8s.io/client-go/informers"
	"kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"

J
jeff 已提交
25 26
	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/labels"
H
hongming 已提交
27 28
	"kubesphere.io/kubesphere/pkg/server/params"
	"sort"
J
jeff 已提交
29 30 31
)

type podSearcher struct {
Z
zryfish 已提交
32 33 34 35 36
	informers informers.SharedInformerFactory
}

func NewPodSearcher(informers informers.SharedInformerFactory) v1alpha2.Interface {
	return &podSearcher{informers: informers}
J
jeff 已提交
37 38
}

Z
zryfish 已提交
39 40
func (s *podSearcher) Get(namespace, name string) (interface{}, error) {
	return s.informers.Core().V1().Pods().Lister().Pods(namespace).Get(name)
H
hongming 已提交
41
}
Z
zryfish 已提交
42

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

H
hongming 已提交
69
func replicaSetBelongToDeployment(replicaSet *appsv1.ReplicaSet, deploymentName string) bool {
Z
zryfish 已提交
70
	for _, owner := range replicaSet.OwnerReferences {
H
hongming 已提交
71
		if owner.Kind == "Deployment" && owner.Name == deploymentName {
Z
zryfish 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
			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 已提交
96
func podBelongToReplicaSet(item *v1.Pod, replicaSetName string) bool {
Z
zryfish 已提交
97
	for _, owner := range item.OwnerReferences {
H
hongming 已提交
98
		if owner.Kind == "ReplicaSet" && owner.Name == replicaSetName {
Z
zryfish 已提交
99 100 101 102 103 104
			return true
		}
	}
	return false
}

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

Z
zryfish 已提交
114 115
func (s *podSearcher) podBelongToDeployment(item *v1.Pod, deploymentName string) bool {
	replicas, err := s.informers.Apps().V1().ReplicaSets().Lister().ReplicaSets(item.Namespace).List(labels.Everything())
Z
zryfish 已提交
116 117 118
	if err != nil {
		return false
	}
H
hongming 已提交
119

Z
zryfish 已提交
120
	for _, r := range replicas {
H
hongming 已提交
121 122
		if replicaSetBelongToDeployment(r, deploymentName) && podBelongToReplicaSet(item, r.Name) {
			return true
Z
zryfish 已提交
123 124
		}
	}
H
hongming 已提交
125

Z
zryfish 已提交
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
}

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

	selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
H
hongming 已提交
146
	if selector.Empty() || !selector.Matches(labels.Set(item.Labels)) {
H
hongming 已提交
147
		return false
Z
zryfish 已提交
148 149 150 151
	}
	return true
}

Z
zryfish 已提交
152
func (s *podSearcher) match(match map[string]string, item *v1.Pod) bool {
J
jeff 已提交
153 154
	for k, v := range match {
		switch k {
Z
zryfish 已提交
155
		case v1alpha2.OwnerKind:
Z
zryfish 已提交
156
			fallthrough
Z
zryfish 已提交
157 158 159 160
		case v1alpha2.OwnerName:
			kind := match[v1alpha2.OwnerKind]
			name := match[v1alpha2.OwnerName]
			if !s.podBelongTo(item, kind, name) {
Z
zryfish 已提交
161 162 163 164 165 166 167 168 169 170 171
				return false
			}
		case "nodeName":
			if item.Spec.NodeName != v {
				return false
			}
		case "pvcName":
			if !podBindPVC(item, v) {
				return false
			}
		case "serviceName":
Z
zryfish 已提交
172
			if !s.podBelongToService(item, v) {
Z
zryfish 已提交
173 174
				return false
			}
J
jeff 已提交
175
		default:
H
hongming 已提交
176
			if !v1alpha2.ObjectMetaExactlyMath(k, v, item.ObjectMeta) {
Z
zryfish 已提交
177 178
				return false
			}
J
jeff 已提交
179 180 181 182 183 184 185
		}
	}
	return true
}

func (*podSearcher) fuzzy(fuzzy map[string]string, item *v1.Pod) bool {
	for k, v := range fuzzy {
H
hongming 已提交
186
		if !v1alpha2.ObjectMetaFuzzyMath(k, v, item.ObjectMeta) {
J
jeff 已提交
187 188 189 190 191 192
			return false
		}
	}
	return true
}

H
hongming 已提交
193
func (*podSearcher) compare(left, right *v1.Pod, orderBy string) bool {
J
jeff 已提交
194
	switch orderBy {
Z
zryfish 已提交
195
	case v1alpha2.StartTime:
H
hongming 已提交
196
		if left.Status.StartTime == nil {
197 198
			return false
		}
H
hongming 已提交
199
		if right.Status.StartTime == nil {
200 201
			return true
		}
H
hongming 已提交
202
		return left.Status.StartTime.Before(right.Status.StartTime)
J
jeff 已提交
203
	default:
H
hongming 已提交
204
		return v1alpha2.ObjectMetaCompare(left.ObjectMeta, right.ObjectMeta, orderBy)
J
jeff 已提交
205 206 207
	}
}

Z
zryfish 已提交
208
func (s *podSearcher) Search(namespace string, conditions *params.Conditions, orderBy string, reverse bool) ([]interface{}, error) {
J
jeff 已提交
209

Z
zryfish 已提交
210
	pods, err := s.informers.Core().V1().Pods().Lister().Pods(namespace).List(labels.Everything())
J
jeff 已提交
211 212 213 214 215 216 217

	if err != nil {
		return nil, err
	}

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

H
hongming 已提交
218
	if len(conditions.Match) == 0 && len(conditions.Fuzzy) == 0 {
J
jeff 已提交
219 220 221
		result = pods
	} else {
		for _, item := range pods {
H
hongming 已提交
222
			if s.match(conditions.Match, item) && s.fuzzy(conditions.Fuzzy, item) {
J
jeff 已提交
223 224 225 226 227 228
				result = append(result, item)
			}
		}
	}
	sort.Slice(result, func(i, j int) bool {
		if reverse {
H
hongming 已提交
229
			i, j = j, i
J
jeff 已提交
230 231 232 233 234 235 236 237 238 239
		}
		return s.compare(result[i], result[j], orderBy)
	})

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