-
Notifications
You must be signed in to change notification settings - Fork 444
/
pods.go
124 lines (106 loc) · 3.44 KB
/
pods.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package kubeutils
import (
"context"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/rest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// GetPodsForDeployment gets all pods backing a deployment that are running and ready
func GetPodsForDeployment(
ctx context.Context,
restConfig *rest.Config,
deploymentName string,
deploymentNamespace string,
) ([]string, error) {
kubeClient, err := kubernetes.NewForConfig(restConfig)
if err != nil {
return nil, err
}
// We change the implementation of this method, to return only pods that are ready
// This is done to reduce the chance that a developer misuses this utility
// If you want to get pods that are not ready, you can use GetPodsForDeploymentWithPredicate
return GetReadyPodsForDeployment(
ctx,
kubeClient,
metav1.ObjectMeta{
Name: deploymentName,
Namespace: deploymentNamespace,
})
}
// GetReadyPodsForDeployment gets all pods backing a deployment that are running and ready
// This function should be preferred over GetPodsForDeployment
func GetReadyPodsForDeployment(
ctx context.Context,
kubeClient *kubernetes.Clientset,
deploy metav1.ObjectMeta,
) ([]string, error) {
// This predicate will return true if and only if the pod is ready
readyPodPredicate := func(pod corev1.Pod) bool {
for _, condition := range pod.Status.Conditions {
if condition.Type == corev1.PodReady {
return true
}
}
return false
}
return GetPodsForDeploymentWithPredicate(ctx, kubeClient, deploy, readyPodPredicate)
}
// GetPodsForDeploymentWithPredicate gets all pods backing a deployment that are running and satisfy the predicate function
func GetPodsForDeploymentWithPredicate(
ctx context.Context,
kubeClient *kubernetes.Clientset,
deploy metav1.ObjectMeta,
predicate func(pod corev1.Pod) bool,
) ([]string, error) {
deployment, err := kubeClient.AppsV1().Deployments(deploy.GetNamespace()).Get(ctx, deploy.GetName(), metav1.GetOptions{})
if err != nil {
return nil, err
}
matchLabels := deployment.Spec.Selector.MatchLabels
listOptions := (&client.ListOptions{
LabelSelector: labels.SelectorFromSet(matchLabels),
FieldSelector: fields.Set{"status.phase": "Running"}.AsSelector(),
}).AsListOptions()
podList, err := kubeClient.CoreV1().Pods(deploy.GetNamespace()).List(ctx, *listOptions)
if err != nil {
return nil, err
}
podNames := make([]string, 0, len(podList.Items))
for _, pod := range podList.Items {
if predicate(pod) {
podNames = append(podNames, pod.Name)
}
}
return podNames, nil
}
// GetPodsForService gets all pods backing a deployment
func GetPodsForService(
ctx context.Context,
restConfig *rest.Config,
serviceName string,
serviceNamespace string,
) ([]string, error) {
kubeClient, err := kubernetes.NewForConfig(restConfig)
if err != nil {
return nil, err
}
service, err := kubeClient.CoreV1().Services(serviceNamespace).Get(ctx, serviceName, metav1.GetOptions{})
if err != nil {
return nil, err
}
matchLabels := service.Spec.Selector
listOptions := (&client.ListOptions{LabelSelector: labels.SelectorFromSet(matchLabels)}).AsListOptions()
podList, err := kubeClient.CoreV1().Pods(serviceNamespace).List(ctx, *listOptions)
if err != nil {
return nil, err
}
pods := make([]string, len(podList.Items))
for i := range podList.Items {
pods[i] = podList.Items[i].Name
}
return pods, nil
}