Look for pods in ownerReferences of PVC (#120427)
* Look for pods in ownerReferences of PVC * Implement for loop instead of using slices package * Add tests for getPodsForPVC function * Make PVC names consistent * Remove volumes part of the pvc owner pod * Do not store result of append in another variable * Fix lint error Kubernetes-commit: 710dceded51d5cf65bc27bca0b0c96f05909b65b
This commit is contained in:
		
							parent
							
								
									ac00f9091c
								
							
						
					
					
						commit
						663031e23e
					
				
							
								
								
									
										4
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										4
									
								
								go.mod
								
								
								
								
							| 
						 | 
				
			
			@ -33,7 +33,7 @@ require (
 | 
			
		|||
	k8s.io/api v0.0.0-20230909181734-5e9982075c8d
 | 
			
		||||
	k8s.io/apimachinery v0.0.0-20230909181434-fd8daa85285e
 | 
			
		||||
	k8s.io/cli-runtime v0.0.0-20230909185656-e7b1ca8f27e9
 | 
			
		||||
	k8s.io/client-go v0.0.0-20230909182134-a73949f10aab
 | 
			
		||||
	k8s.io/client-go v0.0.0-20230912222112-908cc0a33323
 | 
			
		||||
	k8s.io/component-base v0.0.0-20230909183239-67a127246dfb
 | 
			
		||||
	k8s.io/component-helpers v0.0.0-20230909183403-e4a58e244b0d
 | 
			
		||||
	k8s.io/klog/v2 v2.100.1
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ replace (
 | 
			
		|||
	k8s.io/api => k8s.io/api v0.0.0-20230909181734-5e9982075c8d
 | 
			
		||||
	k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20230909181434-fd8daa85285e
 | 
			
		||||
	k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20230909185656-e7b1ca8f27e9
 | 
			
		||||
	k8s.io/client-go => k8s.io/client-go v0.0.0-20230909182134-a73949f10aab
 | 
			
		||||
	k8s.io/client-go => k8s.io/client-go v0.0.0-20230912222112-908cc0a33323
 | 
			
		||||
	k8s.io/code-generator => k8s.io/code-generator v0.0.0-20230909142409-71364b5549ac
 | 
			
		||||
	k8s.io/component-base => k8s.io/component-base v0.0.0-20230909183239-67a127246dfb
 | 
			
		||||
	k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20230909183403-e4a58e244b0d
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										4
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -281,8 +281,8 @@ k8s.io/apimachinery v0.0.0-20230909181434-fd8daa85285e h1:6zC7lfpiLOlGxE9qAFnwTc
 | 
			
		|||
k8s.io/apimachinery v0.0.0-20230909181434-fd8daa85285e/go.mod h1:PdcNQGTeFDzS6zavrEgNmA2CJm+g27ZPKhnUpRfaNek=
 | 
			
		||||
k8s.io/cli-runtime v0.0.0-20230909185656-e7b1ca8f27e9 h1:Nde5fbanpsYobA2IxiHSc/tTHpjZXnULy5eR4Y9xsGs=
 | 
			
		||||
k8s.io/cli-runtime v0.0.0-20230909185656-e7b1ca8f27e9/go.mod h1:Je5DUy1HdTCpxM02CjAT4qqhO8bCAqXLxkz2pSCrWq8=
 | 
			
		||||
k8s.io/client-go v0.0.0-20230909182134-a73949f10aab h1:w/MUuxYXPL9bVZmAswHDagqxQF/6jgY1XjADHBMSEQs=
 | 
			
		||||
k8s.io/client-go v0.0.0-20230909182134-a73949f10aab/go.mod h1:qaThK3dAVeHJKxb7mjB7U3EbGaaGzemzRYp4Fm8ZFKI=
 | 
			
		||||
k8s.io/client-go v0.0.0-20230912222112-908cc0a33323 h1:DC22aUxPtPxP7TBVcznpKfNTlnaVTyyQQm33T6OCESM=
 | 
			
		||||
k8s.io/client-go v0.0.0-20230912222112-908cc0a33323/go.mod h1:qaThK3dAVeHJKxb7mjB7U3EbGaaGzemzRYp4Fm8ZFKI=
 | 
			
		||||
k8s.io/component-base v0.0.0-20230909183239-67a127246dfb h1:6lEuU2Db1Fo8IIhvpazjpSYeCNhwjlr/9mL5UE0+TVU=
 | 
			
		||||
k8s.io/component-base v0.0.0-20230909183239-67a127246dfb/go.mod h1:uKdfM6owEofwQkfFDqlozWjzCIdtSAt8scmNFynp0mQ=
 | 
			
		||||
k8s.io/component-helpers v0.0.0-20230909183403-e4a58e244b0d h1:/mCwSyN5w8TD7nYPmV3u0e6qKoAMVcwNNxOV05JfR6A=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1645,7 +1645,7 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
 | 
			
		|||
 | 
			
		||||
	pc := d.CoreV1().Pods(namespace)
 | 
			
		||||
 | 
			
		||||
	pods, err := getPodsForPVC(pc, pvc.Name, describerSettings)
 | 
			
		||||
	pods, err := getPodsForPVC(pc, pvc, describerSettings)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1655,7 +1655,7 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
 | 
			
		|||
	return describePersistentVolumeClaim(pvc, events, pods)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getPodsForPVC(c corev1client.PodInterface, pvcName string, settings DescriberSettings) ([]corev1.Pod, error) {
 | 
			
		||||
func getPodsForPVC(c corev1client.PodInterface, pvc *corev1.PersistentVolumeClaim, settings DescriberSettings) ([]corev1.Pod, error) {
 | 
			
		||||
	nsPods, err := getPodsInChunks(c, metav1.ListOptions{Limit: settings.ChunkSize})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return []corev1.Pod{}, err
 | 
			
		||||
| 
						 | 
				
			
			@ -1665,12 +1665,40 @@ func getPodsForPVC(c corev1client.PodInterface, pvcName string, settings Describ
 | 
			
		|||
 | 
			
		||||
	for _, pod := range nsPods.Items {
 | 
			
		||||
		for _, volume := range pod.Spec.Volumes {
 | 
			
		||||
			if volume.VolumeSource.PersistentVolumeClaim != nil && volume.VolumeSource.PersistentVolumeClaim.ClaimName == pvcName {
 | 
			
		||||
			if volume.VolumeSource.PersistentVolumeClaim != nil && volume.VolumeSource.PersistentVolumeClaim.ClaimName == pvc.Name {
 | 
			
		||||
				pods = append(pods, pod)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
ownersLoop:
 | 
			
		||||
	for _, ownerRef := range pvc.ObjectMeta.OwnerReferences {
 | 
			
		||||
		if ownerRef.Kind != "Pod" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		podIndex := -1
 | 
			
		||||
		for i, pod := range nsPods.Items {
 | 
			
		||||
			if pod.UID == ownerRef.UID {
 | 
			
		||||
				podIndex = i
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if podIndex == -1 {
 | 
			
		||||
			// Maybe the pod has been deleted
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, pod := range pods {
 | 
			
		||||
			if pod.UID == nsPods.Items[podIndex].UID {
 | 
			
		||||
				// This owner pod is already recorded, look for pods between other owners
 | 
			
		||||
				continue ownersLoop
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pods = append(pods, nsPods.Items[podIndex])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pods, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1994,6 +1994,123 @@ func TestPersistentVolumeClaimDescriber(t *testing.T) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetPodsForPVC(t *testing.T) {
 | 
			
		||||
	goldClassName := "gold"
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name            string
 | 
			
		||||
		pvc             *corev1.PersistentVolumeClaim
 | 
			
		||||
		requiredObjects []runtime.Object
 | 
			
		||||
		expectedPods    []string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "pvc-unused",
 | 
			
		||||
			pvc: &corev1.PersistentVolumeClaim{
 | 
			
		||||
				ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pvc-name"},
 | 
			
		||||
				Spec: corev1.PersistentVolumeClaimSpec{
 | 
			
		||||
					VolumeName:       "volume1",
 | 
			
		||||
					StorageClassName: &goldClassName,
 | 
			
		||||
				},
 | 
			
		||||
				Status: corev1.PersistentVolumeClaimStatus{
 | 
			
		||||
					Phase: corev1.ClaimBound,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPods: []string{},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "pvc-in-pods-volumes-list",
 | 
			
		||||
			pvc: &corev1.PersistentVolumeClaim{
 | 
			
		||||
				ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pvc-name"},
 | 
			
		||||
				Spec: corev1.PersistentVolumeClaimSpec{
 | 
			
		||||
					VolumeName:       "volume1",
 | 
			
		||||
					StorageClassName: &goldClassName,
 | 
			
		||||
				},
 | 
			
		||||
				Status: corev1.PersistentVolumeClaimStatus{
 | 
			
		||||
					Phase: corev1.ClaimBound,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			requiredObjects: []runtime.Object{
 | 
			
		||||
				&corev1.Pod{
 | 
			
		||||
					ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod-name"},
 | 
			
		||||
					Spec: corev1.PodSpec{
 | 
			
		||||
						Volumes: []corev1.Volume{
 | 
			
		||||
							{
 | 
			
		||||
								Name: "volume",
 | 
			
		||||
								VolumeSource: corev1.VolumeSource{
 | 
			
		||||
									PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
 | 
			
		||||
										ClaimName: "pvc-name",
 | 
			
		||||
									},
 | 
			
		||||
								},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPods: []string{"pod-name"},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "pvc-owned-by-pod",
 | 
			
		||||
			pvc: &corev1.PersistentVolumeClaim{
 | 
			
		||||
				ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
					Namespace: "ns",
 | 
			
		||||
					Name:      "pvc-name",
 | 
			
		||||
					OwnerReferences: []metav1.OwnerReference{
 | 
			
		||||
						{
 | 
			
		||||
							Kind: "Pod",
 | 
			
		||||
							Name: "pod-name",
 | 
			
		||||
							UID:  "pod-uid",
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				Spec: corev1.PersistentVolumeClaimSpec{
 | 
			
		||||
					VolumeName:       "volume1",
 | 
			
		||||
					StorageClassName: &goldClassName,
 | 
			
		||||
				},
 | 
			
		||||
				Status: corev1.PersistentVolumeClaimStatus{
 | 
			
		||||
					Phase: corev1.ClaimBound,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			requiredObjects: []runtime.Object{
 | 
			
		||||
				&corev1.Pod{
 | 
			
		||||
					ObjectMeta: metav1.ObjectMeta{Namespace: "ns", Name: "pod-name", UID: "pod-uid"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPods: []string{"pod-name"},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, test := range testCases {
 | 
			
		||||
		t.Run(test.name, func(t *testing.T) {
 | 
			
		||||
			var objects []runtime.Object
 | 
			
		||||
			objects = append(objects, test.requiredObjects...)
 | 
			
		||||
			objects = append(objects, test.pvc)
 | 
			
		||||
			fake := fake.NewSimpleClientset(objects...)
 | 
			
		||||
 | 
			
		||||
			pods, err := getPodsForPVC(fake.CoreV1().Pods(test.pvc.ObjectMeta.Namespace), test.pvc, DescriberSettings{})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Errorf("Unexpected error for test %s: %v", test.name, err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for _, expectedPod := range test.expectedPods {
 | 
			
		||||
				foundPod := false
 | 
			
		||||
				for _, pod := range pods {
 | 
			
		||||
					if pod.Name == expectedPod {
 | 
			
		||||
						foundPod = true
 | 
			
		||||
						break
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if !foundPod {
 | 
			
		||||
					t.Errorf("Expected pod %s, but it was not returned: %v", expectedPod, pods)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(test.expectedPods) != len(pods) {
 | 
			
		||||
				t.Errorf("Expected %d pods, but got %d pods", len(test.expectedPods), len(pods))
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDescribeDeployment(t *testing.T) {
 | 
			
		||||
	labels := map[string]string{"k8s-app": "bar"}
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue