mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	@@ -67,12 +67,12 @@ func TestWarnings(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for _, tc := range testcases {
 | 
						for _, tc := range testcases {
 | 
				
			||||||
		t.Run("podspec_"+tc.name, func(t *testing.T) {
 | 
							t.Run("podspec_"+tc.name, func(t *testing.T) {
 | 
				
			||||||
			actual := sets.NewString(GetWarningsForRuntimeClass(tc.template)...)
 | 
								actual := sets.New[string](GetWarningsForRuntimeClass(tc.template)...)
 | 
				
			||||||
			expected := sets.NewString(tc.expected...)
 | 
								expected := sets.New[string](tc.expected...)
 | 
				
			||||||
			for _, missing := range expected.Difference(actual).List() {
 | 
								for _, missing := range sets.List[string](expected.Difference(actual)) {
 | 
				
			||||||
				t.Errorf("missing: %s", missing)
 | 
									t.Errorf("missing: %s", missing)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, extra := range actual.Difference(expected).List() {
 | 
								for _, extra := range sets.List[string](actual.Difference(expected)) {
 | 
				
			||||||
				t.Errorf("extra: %s", extra)
 | 
									t.Errorf("extra: %s", extra)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -298,12 +298,12 @@ func TestWarnings(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for _, tc := range testcases {
 | 
						for _, tc := range testcases {
 | 
				
			||||||
		t.Run("podspec_"+tc.name, func(t *testing.T) {
 | 
							t.Run("podspec_"+tc.name, func(t *testing.T) {
 | 
				
			||||||
			actual := sets.NewString(GetWarningsForPersistentVolume(tc.template)...)
 | 
								actual := sets.New[string](GetWarningsForPersistentVolume(tc.template)...)
 | 
				
			||||||
			expected := sets.NewString(tc.expected...)
 | 
								expected := sets.New[string](tc.expected...)
 | 
				
			||||||
			for _, missing := range expected.Difference(actual).List() {
 | 
								for _, missing := range sets.List[string](expected.Difference(actual)) {
 | 
				
			||||||
				t.Errorf("missing: %s", missing)
 | 
									t.Errorf("missing: %s", missing)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, extra := range actual.Difference(expected).List() {
 | 
								for _, extra := range sets.List[string](actual.Difference(expected)) {
 | 
				
			||||||
				t.Errorf("extra: %s", extra)
 | 
									t.Errorf("extra: %s", extra)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -571,12 +571,12 @@ func TestWarnings(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for _, tc := range testcases {
 | 
						for _, tc := range testcases {
 | 
				
			||||||
		t.Run("pvcspec_"+tc.name, func(t *testing.T) {
 | 
							t.Run("pvcspec_"+tc.name, func(t *testing.T) {
 | 
				
			||||||
			actual := sets.NewString(GetWarningsForPersistentVolumeClaim(tc.template)...)
 | 
								actual := sets.New[string](GetWarningsForPersistentVolumeClaim(tc.template)...)
 | 
				
			||||||
			expected := sets.NewString(tc.expected...)
 | 
								expected := sets.New[string](tc.expected...)
 | 
				
			||||||
			for _, missing := range expected.Difference(actual).List() {
 | 
								for _, missing := range sets.List[string](expected.Difference(actual)) {
 | 
				
			||||||
				t.Errorf("missing: %s", missing)
 | 
									t.Errorf("missing: %s", missing)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, extra := range actual.Difference(expected).List() {
 | 
								for _, extra := range sets.List[string](actual.Difference(expected)) {
 | 
				
			||||||
				t.Errorf("extra: %s", extra)
 | 
									t.Errorf("extra: %s", extra)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -290,19 +290,19 @@ func TestPodSecrets(t *testing.T) {
 | 
				
			|||||||
									Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.SecretKeyRef"}}}}}}}},
 | 
														Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.SecretKeyRef"}}}}}}}},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	extractedNames := sets.NewString()
 | 
						extractedNames := sets.New[string]()
 | 
				
			||||||
	VisitPodSecretNames(pod, func(name string) bool {
 | 
						VisitPodSecretNames(pod, func(name string) bool {
 | 
				
			||||||
		extractedNames.Insert(name)
 | 
							extractedNames.Insert(name)
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}, AllContainers)
 | 
						}, AllContainers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
 | 
						// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
 | 
				
			||||||
	excludedSecretPaths := sets.NewString(
 | 
						excludedSecretPaths := sets.New[string](
 | 
				
			||||||
		"Spec.Volumes[*].VolumeSource.CephFS.SecretFile",
 | 
							"Spec.Volumes[*].VolumeSource.CephFS.SecretFile",
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
 | 
						// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
 | 
				
			||||||
	// every path here should be represented as an example in the Pod stub above, with the secret name set to the path.
 | 
						// every path here should be represented as an example in the Pod stub above, with the secret name set to the path.
 | 
				
			||||||
	expectedSecretPaths := sets.NewString(
 | 
						expectedSecretPaths := sets.New[string](
 | 
				
			||||||
		"Spec.Containers[*].EnvFrom[*].SecretRef",
 | 
							"Spec.Containers[*].EnvFrom[*].SecretRef",
 | 
				
			||||||
		"Spec.Containers[*].Env[*].ValueFrom.SecretKeyRef",
 | 
							"Spec.Containers[*].Env[*].ValueFrom.SecretKeyRef",
 | 
				
			||||||
		"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].SecretRef",
 | 
							"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].SecretRef",
 | 
				
			||||||
@@ -326,20 +326,20 @@ func TestPodSecrets(t *testing.T) {
 | 
				
			|||||||
	secretPaths := collectResourcePaths(t, "secret", nil, "", reflect.TypeOf(&api.Pod{}))
 | 
						secretPaths := collectResourcePaths(t, "secret", nil, "", reflect.TypeOf(&api.Pod{}))
 | 
				
			||||||
	secretPaths = secretPaths.Difference(excludedSecretPaths)
 | 
						secretPaths = secretPaths.Difference(excludedSecretPaths)
 | 
				
			||||||
	if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
 | 
						if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected secret paths:\n%s", strings.Join(missingPaths.List(), "\n"))
 | 
							t.Logf("Missing expected secret paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
 | 
				
			||||||
		t.Error("Missing expected secret paths. Verify VisitPodSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
 | 
							t.Error("Missing expected secret paths. Verify VisitPodSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
 | 
						if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
 | 
				
			||||||
		t.Logf("Extra secret paths:\n%s", strings.Join(extraPaths.List(), "\n"))
 | 
							t.Logf("Extra secret paths:\n%s", strings.Join(sets.List[string](extraPaths), "\n"))
 | 
				
			||||||
		t.Error("Extra fields with 'secret' in the name found. Verify VisitPodSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
 | 
							t.Error("Extra fields with 'secret' in the name found. Verify VisitPodSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
						if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected secret names:\n%s", strings.Join(missingNames.List(), "\n"))
 | 
							t.Logf("Missing expected secret names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
 | 
				
			||||||
		t.Error("Missing expected secret names. Verify the pod stub above includes these references, then verify VisitPodSecretNames() is correctly finding the missing names")
 | 
							t.Error("Missing expected secret names. Verify the pod stub above includes these references, then verify VisitPodSecretNames() is correctly finding the missing names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
 | 
						if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
 | 
				
			||||||
		t.Logf("Extra secret names:\n%s", strings.Join(extraNames.List(), "\n"))
 | 
							t.Logf("Extra secret names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
 | 
				
			||||||
		t.Error("Extra secret names extracted. Verify VisitPodSecretNames() is correctly extracting secret names")
 | 
							t.Error("Extra secret names extracted. Verify VisitPodSecretNames() is correctly extracting secret names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -360,12 +360,12 @@ func TestPodSecrets(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// collectResourcePaths traverses the object, computing all the struct paths that lead to fields with resourcename in the name.
 | 
					// collectResourcePaths traverses the object, computing all the struct paths that lead to fields with resourcename in the name.
 | 
				
			||||||
func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.String {
 | 
					func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.Set[string] {
 | 
				
			||||||
	resourcename = strings.ToLower(resourcename)
 | 
						resourcename = strings.ToLower(resourcename)
 | 
				
			||||||
	resourcePaths := sets.NewString()
 | 
						resourcePaths := sets.New[string]()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if tp.Kind() == reflect.Pointer {
 | 
						if tp.Kind() == reflect.Pointer {
 | 
				
			||||||
		resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
 | 
							resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path, name, tp.Elem()))...)
 | 
				
			||||||
		return resourcePaths
 | 
							return resourcePaths
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -375,7 +375,7 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	switch tp.Kind() {
 | 
						switch tp.Kind() {
 | 
				
			||||||
	case reflect.Pointer:
 | 
						case reflect.Pointer:
 | 
				
			||||||
		resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
 | 
							resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path, name, tp.Elem()))...)
 | 
				
			||||||
	case reflect.Struct:
 | 
						case reflect.Struct:
 | 
				
			||||||
		// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
 | 
							// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
 | 
				
			||||||
		// it contains cycles so it's easiest to just skip it.
 | 
							// it contains cycles so it's easiest to just skip it.
 | 
				
			||||||
@@ -384,14 +384,14 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		for i := 0; i < tp.NumField(); i++ {
 | 
							for i := 0; i < tp.NumField(); i++ {
 | 
				
			||||||
			field := tp.Field(i)
 | 
								field := tp.Field(i)
 | 
				
			||||||
			resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)
 | 
								resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type))...)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case reflect.Interface:
 | 
						case reflect.Interface:
 | 
				
			||||||
		t.Errorf("cannot find %s fields in interface{} field %s", resourcename, path.String())
 | 
							t.Errorf("cannot find %s fields in interface{} field %s", resourcename, path.String())
 | 
				
			||||||
	case reflect.Map:
 | 
						case reflect.Map:
 | 
				
			||||||
		resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
 | 
							resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()))...)
 | 
				
			||||||
	case reflect.Slice:
 | 
						case reflect.Slice:
 | 
				
			||||||
		resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
 | 
							resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()))...)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		// all primitive types
 | 
							// all primitive types
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -448,7 +448,7 @@ func TestPodConfigmaps(t *testing.T) {
 | 
				
			|||||||
							Name: "Spec.Volumes[*].VolumeSource.ConfigMap"}}}}},
 | 
												Name: "Spec.Volumes[*].VolumeSource.ConfigMap"}}}}},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	extractedNames := sets.NewString()
 | 
						extractedNames := sets.New[string]()
 | 
				
			||||||
	VisitPodConfigmapNames(pod, func(name string) bool {
 | 
						VisitPodConfigmapNames(pod, func(name string) bool {
 | 
				
			||||||
		extractedNames.Insert(name)
 | 
							extractedNames.Insert(name)
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
@@ -456,7 +456,7 @@ func TestPodConfigmaps(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// expectedPaths holds struct paths to fields with "ConfigMap" in the name that are references to ConfigMap API objects.
 | 
						// expectedPaths holds struct paths to fields with "ConfigMap" in the name that are references to ConfigMap API objects.
 | 
				
			||||||
	// every path here should be represented as an example in the Pod stub above, with the ConfigMap name set to the path.
 | 
						// every path here should be represented as an example in the Pod stub above, with the ConfigMap name set to the path.
 | 
				
			||||||
	expectedPaths := sets.NewString(
 | 
						expectedPaths := sets.New[string](
 | 
				
			||||||
		"Spec.Containers[*].EnvFrom[*].ConfigMapRef",
 | 
							"Spec.Containers[*].EnvFrom[*].ConfigMapRef",
 | 
				
			||||||
		"Spec.Containers[*].Env[*].ValueFrom.ConfigMapKeyRef",
 | 
							"Spec.Containers[*].Env[*].ValueFrom.ConfigMapKeyRef",
 | 
				
			||||||
		"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].ConfigMapRef",
 | 
							"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].ConfigMapRef",
 | 
				
			||||||
@@ -468,20 +468,20 @@ func TestPodConfigmaps(t *testing.T) {
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
	collectPaths := collectResourcePaths(t, "ConfigMap", nil, "", reflect.TypeOf(&api.Pod{}))
 | 
						collectPaths := collectResourcePaths(t, "ConfigMap", nil, "", reflect.TypeOf(&api.Pod{}))
 | 
				
			||||||
	if missingPaths := expectedPaths.Difference(collectPaths); len(missingPaths) > 0 {
 | 
						if missingPaths := expectedPaths.Difference(collectPaths); len(missingPaths) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected paths:\n%s", strings.Join(missingPaths.List(), "\n"))
 | 
							t.Logf("Missing expected paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
 | 
				
			||||||
		t.Error("Missing expected paths. Verify VisitPodConfigmapNames() is correctly finding the missing paths, then correct expectedPaths")
 | 
							t.Error("Missing expected paths. Verify VisitPodConfigmapNames() is correctly finding the missing paths, then correct expectedPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraPaths := collectPaths.Difference(expectedPaths); len(extraPaths) > 0 {
 | 
						if extraPaths := collectPaths.Difference(expectedPaths); len(extraPaths) > 0 {
 | 
				
			||||||
		t.Logf("Extra paths:\n%s", strings.Join(extraPaths.List(), "\n"))
 | 
							t.Logf("Extra paths:\n%s", strings.Join(sets.List[string](extraPaths), "\n"))
 | 
				
			||||||
		t.Error("Extra fields with resource in the name found. Verify VisitPodConfigmapNames() is including these fields if appropriate, then correct expectedPaths")
 | 
							t.Error("Extra fields with resource in the name found. Verify VisitPodConfigmapNames() is including these fields if appropriate, then correct expectedPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if missingNames := expectedPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
						if missingNames := expectedPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected names:\n%s", strings.Join(missingNames.List(), "\n"))
 | 
							t.Logf("Missing expected names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
 | 
				
			||||||
		t.Error("Missing expected names. Verify the pod stub above includes these references, then verify VisitPodConfigmapNames() is correctly finding the missing names")
 | 
							t.Error("Missing expected names. Verify the pod stub above includes these references, then verify VisitPodConfigmapNames() is correctly finding the missing names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraNames := extractedNames.Difference(expectedPaths); len(extraNames) > 0 {
 | 
						if extraNames := extractedNames.Difference(expectedPaths); len(extraNames) > 0 {
 | 
				
			||||||
		t.Logf("Extra names:\n%s", strings.Join(extraNames.List(), "\n"))
 | 
							t.Logf("Extra names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
 | 
				
			||||||
		t.Error("Extra names extracted. Verify VisitPodConfigmapNames() is correctly extracting resource names")
 | 
							t.Error("Extra names extracted. Verify VisitPodConfigmapNames() is correctly extracting resource names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -170,7 +170,7 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// duplicate hostAliases (#91670, #58477)
 | 
						// duplicate hostAliases (#91670, #58477)
 | 
				
			||||||
	if len(podSpec.HostAliases) > 1 {
 | 
						if len(podSpec.HostAliases) > 1 {
 | 
				
			||||||
		items := sets.NewString()
 | 
							items := sets.New[string]()
 | 
				
			||||||
		for i, item := range podSpec.HostAliases {
 | 
							for i, item := range podSpec.HostAliases {
 | 
				
			||||||
			if items.Has(item.IP) {
 | 
								if items.Has(item.IP) {
 | 
				
			||||||
				warnings = append(warnings, fmt.Sprintf("%s: duplicate ip %q", fieldPath.Child("spec", "hostAliases").Index(i).Child("ip"), item.IP))
 | 
									warnings = append(warnings, fmt.Sprintf("%s: duplicate ip %q", fieldPath.Child("spec", "hostAliases").Index(i).Child("ip"), item.IP))
 | 
				
			||||||
@@ -182,7 +182,7 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// duplicate imagePullSecrets (#91629, #58477)
 | 
						// duplicate imagePullSecrets (#91629, #58477)
 | 
				
			||||||
	if len(podSpec.ImagePullSecrets) > 1 {
 | 
						if len(podSpec.ImagePullSecrets) > 1 {
 | 
				
			||||||
		items := sets.NewString()
 | 
							items := sets.New[string]()
 | 
				
			||||||
		for i, item := range podSpec.ImagePullSecrets {
 | 
							for i, item := range podSpec.ImagePullSecrets {
 | 
				
			||||||
			if items.Has(item.Name) {
 | 
								if items.Has(item.Name) {
 | 
				
			||||||
				warnings = append(warnings, fmt.Sprintf("%s: duplicate name %q", fieldPath.Child("spec", "imagePullSecrets").Index(i).Child("name"), item.Name))
 | 
									warnings = append(warnings, fmt.Sprintf("%s: duplicate name %q", fieldPath.Child("spec", "imagePullSecrets").Index(i).Child("name"), item.Name))
 | 
				
			||||||
@@ -237,7 +237,7 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// duplicate containers[*].env (#86163, #93266, #58477)
 | 
							// duplicate containers[*].env (#86163, #93266, #58477)
 | 
				
			||||||
		if len(c.Env) > 1 {
 | 
							if len(c.Env) > 1 {
 | 
				
			||||||
			items := sets.NewString()
 | 
								items := sets.New[string]()
 | 
				
			||||||
			for i, item := range c.Env {
 | 
								for i, item := range c.Env {
 | 
				
			||||||
				if items.Has(item.Name) {
 | 
									if items.Has(item.Name) {
 | 
				
			||||||
					// a previous value exists, but it might be OK
 | 
										// a previous value exists, but it might be OK
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1066,12 +1066,12 @@ func TestWarnings(t *testing.T) {
 | 
				
			|||||||
			if tc.oldTemplate != nil {
 | 
								if tc.oldTemplate != nil {
 | 
				
			||||||
				oldTemplate = tc.oldTemplate
 | 
									oldTemplate = tc.oldTemplate
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			actual := sets.NewString(GetWarningsForPodTemplate(context.TODO(), nil, tc.template, oldTemplate)...)
 | 
								actual := sets.New[string](GetWarningsForPodTemplate(context.TODO(), nil, tc.template, oldTemplate)...)
 | 
				
			||||||
			expected := sets.NewString(tc.expected...)
 | 
								expected := sets.New[string](tc.expected...)
 | 
				
			||||||
			for _, missing := range expected.Difference(actual).List() {
 | 
								for _, missing := range sets.List[string](expected.Difference(actual)) {
 | 
				
			||||||
				t.Errorf("missing: %s", missing)
 | 
									t.Errorf("missing: %s", missing)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, extra := range actual.Difference(expected).List() {
 | 
								for _, extra := range sets.List[string](actual.Difference(expected)) {
 | 
				
			||||||
				t.Errorf("extra: %s", extra)
 | 
									t.Errorf("extra: %s", extra)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
@@ -1084,12 +1084,12 @@ func TestWarnings(t *testing.T) {
 | 
				
			|||||||
					Spec:       tc.template.Spec,
 | 
										Spec:       tc.template.Spec,
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			actual := sets.NewString(GetWarningsForPod(context.TODO(), pod, &api.Pod{})...)
 | 
								actual := sets.New[string](GetWarningsForPod(context.TODO(), pod, &api.Pod{})...)
 | 
				
			||||||
			expected := sets.NewString(tc.expected...)
 | 
								expected := sets.New[string](tc.expected...)
 | 
				
			||||||
			for _, missing := range expected.Difference(actual).List() {
 | 
								for _, missing := range sets.List[string](expected.Difference(actual)) {
 | 
				
			||||||
				t.Errorf("missing: %s", missing)
 | 
									t.Errorf("missing: %s", missing)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, extra := range actual.Difference(expected).List() {
 | 
								for _, extra := range sets.List[string](actual.Difference(expected)) {
 | 
				
			||||||
				t.Errorf("extra: %s", extra)
 | 
									t.Errorf("extra: %s", extra)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,12 +76,12 @@ func TestStorageClassWarnings(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for _, tc := range testcases {
 | 
						for _, tc := range testcases {
 | 
				
			||||||
		t.Run("podspec_"+tc.name, func(t *testing.T) {
 | 
							t.Run("podspec_"+tc.name, func(t *testing.T) {
 | 
				
			||||||
			actual := sets.NewString(GetWarningsForStorageClass(tc.template)...)
 | 
								actual := sets.New[string](GetWarningsForStorageClass(tc.template)...)
 | 
				
			||||||
			expected := sets.NewString(tc.expected...)
 | 
								expected := sets.New[string](tc.expected...)
 | 
				
			||||||
			for _, missing := range expected.Difference(actual).List() {
 | 
								for _, missing := range sets.List[string](expected.Difference(actual)) {
 | 
				
			||||||
				t.Errorf("missing: %s", missing)
 | 
									t.Errorf("missing: %s", missing)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, extra := range actual.Difference(expected).List() {
 | 
								for _, extra := range sets.List[string](actual.Difference(expected)) {
 | 
				
			||||||
				t.Errorf("extra: %s", extra)
 | 
									t.Errorf("extra: %s", extra)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
@@ -157,12 +157,12 @@ func TestCSIStorageCapacityWarnings(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for _, tc := range testcases {
 | 
						for _, tc := range testcases {
 | 
				
			||||||
		t.Run("podspec_"+tc.name, func(t *testing.T) {
 | 
							t.Run("podspec_"+tc.name, func(t *testing.T) {
 | 
				
			||||||
			actual := sets.NewString(GetWarningsForCSIStorageCapacity(tc.template)...)
 | 
								actual := sets.New[string](GetWarningsForCSIStorageCapacity(tc.template)...)
 | 
				
			||||||
			expected := sets.NewString(tc.expected...)
 | 
								expected := sets.New[string](tc.expected...)
 | 
				
			||||||
			for _, missing := range expected.Difference(actual).List() {
 | 
								for _, missing := range sets.List[string](expected.Difference(actual)) {
 | 
				
			||||||
				t.Errorf("missing: %s", missing)
 | 
									t.Errorf("missing: %s", missing)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, extra := range actual.Difference(expected).List() {
 | 
								for _, extra := range sets.List[string](actual.Difference(expected)) {
 | 
				
			||||||
				t.Errorf("extra: %s", extra)
 | 
									t.Errorf("extra: %s", extra)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -149,7 +149,7 @@ func TestSpecificKind(t *testing.T) {
 | 
				
			|||||||
	roundtrip.RoundTripSpecificKind(t, internalGVK, legacyscheme.Scheme, legacyscheme.Codecs, fuzzer, nil)
 | 
						roundtrip.RoundTripSpecificKind(t, internalGVK, legacyscheme.Scheme, legacyscheme.Codecs, fuzzer, nil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var nonRoundTrippableTypes = sets.NewString(
 | 
					var nonRoundTrippableTypes = sets.New[string](
 | 
				
			||||||
	"ExportOptions",
 | 
						"ExportOptions",
 | 
				
			||||||
	"GetOptions",
 | 
						"GetOptions",
 | 
				
			||||||
	// WatchEvent does not include kind and version and can only be deserialized
 | 
						// WatchEvent does not include kind and version and can only be deserialized
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -157,8 +157,8 @@ func TestPVSecrets(t *testing.T) {
 | 
				
			|||||||
						Name:      "Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef",
 | 
											Name:      "Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef",
 | 
				
			||||||
						Namespace: "csi"}}}}},
 | 
											Namespace: "csi"}}}}},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	extractedNames := sets.NewString()
 | 
						extractedNames := sets.New[string]()
 | 
				
			||||||
	extractedNamesWithNamespace := sets.NewString()
 | 
						extractedNamesWithNamespace := sets.New[string]()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, pv := range pvs {
 | 
						for _, pv := range pvs {
 | 
				
			||||||
		VisitPVSecretNames(pv, func(namespace, name string, kubeletVisible bool) bool {
 | 
							VisitPVSecretNames(pv, func(namespace, name string, kubeletVisible bool) bool {
 | 
				
			||||||
@@ -169,13 +169,13 @@ func TestPVSecrets(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
 | 
						// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
 | 
				
			||||||
	excludedSecretPaths := sets.NewString(
 | 
						excludedSecretPaths := sets.New[string](
 | 
				
			||||||
		"Spec.PersistentVolumeSource.CephFS.SecretFile",
 | 
							"Spec.PersistentVolumeSource.CephFS.SecretFile",
 | 
				
			||||||
		"Spec.PersistentVolumeSource.AzureFile.SecretNamespace",
 | 
							"Spec.PersistentVolumeSource.AzureFile.SecretNamespace",
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
 | 
						// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
 | 
				
			||||||
	// every path here should be represented as an example in the PV stub above, with the secret name set to the path.
 | 
						// every path here should be represented as an example in the PV stub above, with the secret name set to the path.
 | 
				
			||||||
	expectedSecretPaths := sets.NewString(
 | 
						expectedSecretPaths := sets.New[string](
 | 
				
			||||||
		"Spec.PersistentVolumeSource.AzureFile.SecretName",
 | 
							"Spec.PersistentVolumeSource.AzureFile.SecretName",
 | 
				
			||||||
		"Spec.PersistentVolumeSource.CephFS.SecretRef",
 | 
							"Spec.PersistentVolumeSource.CephFS.SecretRef",
 | 
				
			||||||
		"Spec.PersistentVolumeSource.Cinder.SecretRef",
 | 
							"Spec.PersistentVolumeSource.Cinder.SecretRef",
 | 
				
			||||||
@@ -193,24 +193,24 @@ func TestPVSecrets(t *testing.T) {
 | 
				
			|||||||
	secretPaths := collectSecretPaths(t, nil, "", reflect.TypeOf(&api.PersistentVolume{}))
 | 
						secretPaths := collectSecretPaths(t, nil, "", reflect.TypeOf(&api.PersistentVolume{}))
 | 
				
			||||||
	secretPaths = secretPaths.Difference(excludedSecretPaths)
 | 
						secretPaths = secretPaths.Difference(excludedSecretPaths)
 | 
				
			||||||
	if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
 | 
						if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected secret paths:\n%s", strings.Join(missingPaths.List(), "\n"))
 | 
							t.Logf("Missing expected secret paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
 | 
				
			||||||
		t.Error("Missing expected secret paths. Verify VisitPVSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
 | 
							t.Error("Missing expected secret paths. Verify VisitPVSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
 | 
						if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
 | 
				
			||||||
		t.Logf("Extra secret paths:\n%s", strings.Join(extraPaths.List(), "\n"))
 | 
							t.Logf("Extra secret paths:\n%s", strings.Join(sets.List[string](extraPaths), "\n"))
 | 
				
			||||||
		t.Error("Extra fields with 'secret' in the name found. Verify VisitPVSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
 | 
							t.Error("Extra fields with 'secret' in the name found. Verify VisitPVSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
						if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected secret names:\n%s", strings.Join(missingNames.List(), "\n"))
 | 
							t.Logf("Missing expected secret names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
 | 
				
			||||||
		t.Error("Missing expected secret names. Verify the PV stub above includes these references, then verify VisitPVSecretNames() is correctly finding the missing names")
 | 
							t.Error("Missing expected secret names. Verify the PV stub above includes these references, then verify VisitPVSecretNames() is correctly finding the missing names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
 | 
						if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
 | 
				
			||||||
		t.Logf("Extra secret names:\n%s", strings.Join(extraNames.List(), "\n"))
 | 
							t.Logf("Extra secret names:\n%s", strings.Join(sets.List(extraNames), "\n"))
 | 
				
			||||||
		t.Error("Extra secret names extracted. Verify VisitPVSecretNames() is correctly extracting secret names")
 | 
							t.Error("Extra secret names extracted. Verify VisitPVSecretNames() is correctly extracting secret names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	expectedNamespacedNames := sets.NewString(
 | 
						expectedNamespacedNames := sets.New[string](
 | 
				
			||||||
		"claimrefns/Spec.PersistentVolumeSource.AzureFile.SecretName",
 | 
							"claimrefns/Spec.PersistentVolumeSource.AzureFile.SecretName",
 | 
				
			||||||
		"Spec.PersistentVolumeSource.AzureFile.SecretNamespace/Spec.PersistentVolumeSource.AzureFile.SecretName",
 | 
							"Spec.PersistentVolumeSource.AzureFile.SecretNamespace/Spec.PersistentVolumeSource.AzureFile.SecretName",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -240,11 +240,11 @@ func TestPVSecrets(t *testing.T) {
 | 
				
			|||||||
		"csi/Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef",
 | 
							"csi/Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef",
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if missingNames := expectedNamespacedNames.Difference(extractedNamesWithNamespace); len(missingNames) > 0 {
 | 
						if missingNames := expectedNamespacedNames.Difference(extractedNamesWithNamespace); len(missingNames) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected namespaced names:\n%s", strings.Join(missingNames.List(), "\n"))
 | 
							t.Logf("Missing expected namespaced names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
 | 
				
			||||||
		t.Error("Missing expected namespaced names. Verify the PV stub above includes these references, then verify VisitPVSecretNames() is correctly finding the missing names")
 | 
							t.Error("Missing expected namespaced names. Verify the PV stub above includes these references, then verify VisitPVSecretNames() is correctly finding the missing names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraNames := extractedNamesWithNamespace.Difference(expectedNamespacedNames); len(extraNames) > 0 {
 | 
						if extraNames := extractedNamesWithNamespace.Difference(expectedNamespacedNames); len(extraNames) > 0 {
 | 
				
			||||||
		t.Logf("Extra namespaced names:\n%s", strings.Join(extraNames.List(), "\n"))
 | 
							t.Logf("Extra namespaced names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
 | 
				
			||||||
		t.Error("Extra namespaced names extracted. Verify VisitPVSecretNames() is correctly extracting secret names")
 | 
							t.Error("Extra namespaced names extracted. Verify VisitPVSecretNames() is correctly extracting secret names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -263,11 +263,11 @@ func TestPVSecrets(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// collectSecretPaths traverses the object, computing all the struct paths that lead to fields with "secret" in the name.
 | 
					// collectSecretPaths traverses the object, computing all the struct paths that lead to fields with "secret" in the name.
 | 
				
			||||||
func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.Type) sets.String {
 | 
					func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.Type) sets.Set[string] {
 | 
				
			||||||
	secretPaths := sets.NewString()
 | 
						secretPaths := sets.New[string]()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if tp.Kind() == reflect.Pointer {
 | 
						if tp.Kind() == reflect.Pointer {
 | 
				
			||||||
		secretPaths.Insert(collectSecretPaths(t, path, name, tp.Elem()).List()...)
 | 
							secretPaths.Insert(sets.List[string](collectSecretPaths(t, path, name, tp.Elem()))...)
 | 
				
			||||||
		return secretPaths
 | 
							return secretPaths
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -277,7 +277,7 @@ func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	switch tp.Kind() {
 | 
						switch tp.Kind() {
 | 
				
			||||||
	case reflect.Pointer:
 | 
						case reflect.Pointer:
 | 
				
			||||||
		secretPaths.Insert(collectSecretPaths(t, path, name, tp.Elem()).List()...)
 | 
							secretPaths.Insert(sets.List[string](collectSecretPaths(t, path, name, tp.Elem()))...)
 | 
				
			||||||
	case reflect.Struct:
 | 
						case reflect.Struct:
 | 
				
			||||||
		// ObjectMeta should not have any field with the word "secret" in it;
 | 
							// ObjectMeta should not have any field with the word "secret" in it;
 | 
				
			||||||
		// it contains cycles so it's easiest to just skip it.
 | 
							// it contains cycles so it's easiest to just skip it.
 | 
				
			||||||
@@ -286,14 +286,14 @@ func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		for i := 0; i < tp.NumField(); i++ {
 | 
							for i := 0; i < tp.NumField(); i++ {
 | 
				
			||||||
			field := tp.Field(i)
 | 
								field := tp.Field(i)
 | 
				
			||||||
			secretPaths.Insert(collectSecretPaths(t, path.Child(field.Name), field.Name, field.Type).List()...)
 | 
								secretPaths.Insert(sets.List[string](collectSecretPaths(t, path.Child(field.Name), field.Name, field.Type))...)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case reflect.Interface:
 | 
						case reflect.Interface:
 | 
				
			||||||
		t.Errorf("cannot find secret fields in interface{} field %s", path.String())
 | 
							t.Errorf("cannot find secret fields in interface{} field %s", path.String())
 | 
				
			||||||
	case reflect.Map:
 | 
						case reflect.Map:
 | 
				
			||||||
		secretPaths.Insert(collectSecretPaths(t, path.Key("*"), "", tp.Elem()).List()...)
 | 
							secretPaths.Insert(sets.List[string](collectSecretPaths(t, path.Key("*"), "", tp.Elem()))...)
 | 
				
			||||||
	case reflect.Slice:
 | 
						case reflect.Slice:
 | 
				
			||||||
		secretPaths.Insert(collectSecretPaths(t, path.Key("*"), "", tp.Elem()).List()...)
 | 
							secretPaths.Insert(sets.List[string](collectSecretPaths(t, path.Key("*"), "", tp.Elem()))...)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		// all primitive types
 | 
							// all primitive types
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -453,19 +453,19 @@ func TestPodSecrets(t *testing.T) {
 | 
				
			|||||||
									Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.SecretKeyRef"}}}}}}}},
 | 
														Name: "Spec.EphemeralContainers[*].EphemeralContainerCommon.Env[*].ValueFrom.SecretKeyRef"}}}}}}}},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	extractedNames := sets.NewString()
 | 
						extractedNames := sets.New[string]()
 | 
				
			||||||
	VisitPodSecretNames(pod, func(name string) bool {
 | 
						VisitPodSecretNames(pod, func(name string) bool {
 | 
				
			||||||
		extractedNames.Insert(name)
 | 
							extractedNames.Insert(name)
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
 | 
						// excludedSecretPaths holds struct paths to fields with "secret" in the name that are not actually references to secret API objects
 | 
				
			||||||
	excludedSecretPaths := sets.NewString(
 | 
						excludedSecretPaths := sets.New[string](
 | 
				
			||||||
		"Spec.Volumes[*].VolumeSource.CephFS.SecretFile",
 | 
							"Spec.Volumes[*].VolumeSource.CephFS.SecretFile",
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
 | 
						// expectedSecretPaths holds struct paths to fields with "secret" in the name that are references to secret API objects.
 | 
				
			||||||
	// every path here should be represented as an example in the Pod stub above, with the secret name set to the path.
 | 
						// every path here should be represented as an example in the Pod stub above, with the secret name set to the path.
 | 
				
			||||||
	expectedSecretPaths := sets.NewString(
 | 
						expectedSecretPaths := sets.New[string](
 | 
				
			||||||
		"Spec.Containers[*].EnvFrom[*].SecretRef",
 | 
							"Spec.Containers[*].EnvFrom[*].SecretRef",
 | 
				
			||||||
		"Spec.Containers[*].Env[*].ValueFrom.SecretKeyRef",
 | 
							"Spec.Containers[*].Env[*].ValueFrom.SecretKeyRef",
 | 
				
			||||||
		"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].SecretRef",
 | 
							"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].SecretRef",
 | 
				
			||||||
@@ -489,20 +489,20 @@ func TestPodSecrets(t *testing.T) {
 | 
				
			|||||||
	secretPaths := collectResourcePaths(t, "secret", nil, "", reflect.TypeOf(&v1.Pod{}))
 | 
						secretPaths := collectResourcePaths(t, "secret", nil, "", reflect.TypeOf(&v1.Pod{}))
 | 
				
			||||||
	secretPaths = secretPaths.Difference(excludedSecretPaths)
 | 
						secretPaths = secretPaths.Difference(excludedSecretPaths)
 | 
				
			||||||
	if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
 | 
						if missingPaths := expectedSecretPaths.Difference(secretPaths); len(missingPaths) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected secret paths:\n%s", strings.Join(missingPaths.List(), "\n"))
 | 
							t.Logf("Missing expected secret paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
 | 
				
			||||||
		t.Error("Missing expected secret paths. Verify VisitPodSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
 | 
							t.Error("Missing expected secret paths. Verify VisitPodSecretNames() is correctly finding the missing paths, then correct expectedSecretPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
 | 
						if extraPaths := secretPaths.Difference(expectedSecretPaths); len(extraPaths) > 0 {
 | 
				
			||||||
		t.Logf("Extra secret paths:\n%s", strings.Join(extraPaths.List(), "\n"))
 | 
							t.Logf("Extra secret paths:\n%s", strings.Join(sets.List(extraPaths), "\n"))
 | 
				
			||||||
		t.Error("Extra fields with 'secret' in the name found. Verify VisitPodSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
 | 
							t.Error("Extra fields with 'secret' in the name found. Verify VisitPodSecretNames() is including these fields if appropriate, then correct expectedSecretPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
						if missingNames := expectedSecretPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected secret names:\n%s", strings.Join(missingNames.List(), "\n"))
 | 
							t.Logf("Missing expected secret names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
 | 
				
			||||||
		t.Error("Missing expected secret names. Verify the pod stub above includes these references, then verify VisitPodSecretNames() is correctly finding the missing names")
 | 
							t.Error("Missing expected secret names. Verify the pod stub above includes these references, then verify VisitPodSecretNames() is correctly finding the missing names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
 | 
						if extraNames := extractedNames.Difference(expectedSecretPaths); len(extraNames) > 0 {
 | 
				
			||||||
		t.Logf("Extra secret names:\n%s", strings.Join(extraNames.List(), "\n"))
 | 
							t.Logf("Extra secret names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
 | 
				
			||||||
		t.Error("Extra secret names extracted. Verify VisitPodSecretNames() is correctly extracting secret names")
 | 
							t.Error("Extra secret names extracted. Verify VisitPodSecretNames() is correctly extracting secret names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -523,12 +523,12 @@ func TestPodSecrets(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// collectResourcePaths traverses the object, computing all the struct paths that lead to fields with resourcename in the name.
 | 
					// collectResourcePaths traverses the object, computing all the struct paths that lead to fields with resourcename in the name.
 | 
				
			||||||
func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.String {
 | 
					func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, name string, tp reflect.Type) sets.Set[string] {
 | 
				
			||||||
	resourcename = strings.ToLower(resourcename)
 | 
						resourcename = strings.ToLower(resourcename)
 | 
				
			||||||
	resourcePaths := sets.NewString()
 | 
						resourcePaths := sets.New[string]()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if tp.Kind() == reflect.Pointer {
 | 
						if tp.Kind() == reflect.Pointer {
 | 
				
			||||||
		resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
 | 
							resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path, name, tp.Elem()))...)
 | 
				
			||||||
		return resourcePaths
 | 
							return resourcePaths
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -538,7 +538,7 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	switch tp.Kind() {
 | 
						switch tp.Kind() {
 | 
				
			||||||
	case reflect.Pointer:
 | 
						case reflect.Pointer:
 | 
				
			||||||
		resourcePaths.Insert(collectResourcePaths(t, resourcename, path, name, tp.Elem()).List()...)
 | 
							resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path, name, tp.Elem()))...)
 | 
				
			||||||
	case reflect.Struct:
 | 
						case reflect.Struct:
 | 
				
			||||||
		// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
 | 
							// ObjectMeta is generic and therefore should never have a field with a specific resource's name;
 | 
				
			||||||
		// it contains cycles so it's easiest to just skip it.
 | 
							// it contains cycles so it's easiest to just skip it.
 | 
				
			||||||
@@ -547,14 +547,14 @@ func collectResourcePaths(t *testing.T, resourcename string, path *field.Path, n
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		for i := 0; i < tp.NumField(); i++ {
 | 
							for i := 0; i < tp.NumField(); i++ {
 | 
				
			||||||
			field := tp.Field(i)
 | 
								field := tp.Field(i)
 | 
				
			||||||
			resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type).List()...)
 | 
								resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Child(field.Name), field.Name, field.Type))...)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case reflect.Interface:
 | 
						case reflect.Interface:
 | 
				
			||||||
		t.Errorf("cannot find %s fields in interface{} field %s", resourcename, path.String())
 | 
							t.Errorf("cannot find %s fields in interface{} field %s", resourcename, path.String())
 | 
				
			||||||
	case reflect.Map:
 | 
						case reflect.Map:
 | 
				
			||||||
		resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
 | 
							resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()))...)
 | 
				
			||||||
	case reflect.Slice:
 | 
						case reflect.Slice:
 | 
				
			||||||
		resourcePaths.Insert(collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()).List()...)
 | 
							resourcePaths.Insert(sets.List[string](collectResourcePaths(t, resourcename, path.Key("*"), "", tp.Elem()))...)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		// all primitive types
 | 
							// all primitive types
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -611,7 +611,7 @@ func TestPodConfigmaps(t *testing.T) {
 | 
				
			|||||||
							Name: "Spec.Volumes[*].VolumeSource.ConfigMap"}}}}},
 | 
												Name: "Spec.Volumes[*].VolumeSource.ConfigMap"}}}}},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	extractedNames := sets.NewString()
 | 
						extractedNames := sets.New[string]()
 | 
				
			||||||
	VisitPodConfigmapNames(pod, func(name string) bool {
 | 
						VisitPodConfigmapNames(pod, func(name string) bool {
 | 
				
			||||||
		extractedNames.Insert(name)
 | 
							extractedNames.Insert(name)
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
@@ -619,7 +619,7 @@ func TestPodConfigmaps(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// expectedPaths holds struct paths to fields with "ConfigMap" in the name that are references to ConfigMap API objects.
 | 
						// expectedPaths holds struct paths to fields with "ConfigMap" in the name that are references to ConfigMap API objects.
 | 
				
			||||||
	// every path here should be represented as an example in the Pod stub above, with the ConfigMap name set to the path.
 | 
						// every path here should be represented as an example in the Pod stub above, with the ConfigMap name set to the path.
 | 
				
			||||||
	expectedPaths := sets.NewString(
 | 
						expectedPaths := sets.New[string](
 | 
				
			||||||
		"Spec.Containers[*].EnvFrom[*].ConfigMapRef",
 | 
							"Spec.Containers[*].EnvFrom[*].ConfigMapRef",
 | 
				
			||||||
		"Spec.Containers[*].Env[*].ValueFrom.ConfigMapKeyRef",
 | 
							"Spec.Containers[*].Env[*].ValueFrom.ConfigMapKeyRef",
 | 
				
			||||||
		"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].ConfigMapRef",
 | 
							"Spec.EphemeralContainers[*].EphemeralContainerCommon.EnvFrom[*].ConfigMapRef",
 | 
				
			||||||
@@ -631,20 +631,20 @@ func TestPodConfigmaps(t *testing.T) {
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
	collectPaths := collectResourcePaths(t, "ConfigMap", nil, "", reflect.TypeOf(&v1.Pod{}))
 | 
						collectPaths := collectResourcePaths(t, "ConfigMap", nil, "", reflect.TypeOf(&v1.Pod{}))
 | 
				
			||||||
	if missingPaths := expectedPaths.Difference(collectPaths); len(missingPaths) > 0 {
 | 
						if missingPaths := expectedPaths.Difference(collectPaths); len(missingPaths) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected paths:\n%s", strings.Join(missingPaths.List(), "\n"))
 | 
							t.Logf("Missing expected paths:\n%s", strings.Join(sets.List[string](missingPaths), "\n"))
 | 
				
			||||||
		t.Error("Missing expected paths. Verify VisitPodConfigmapNames() is correctly finding the missing paths, then correct expectedPaths")
 | 
							t.Error("Missing expected paths. Verify VisitPodConfigmapNames() is correctly finding the missing paths, then correct expectedPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraPaths := collectPaths.Difference(expectedPaths); len(extraPaths) > 0 {
 | 
						if extraPaths := collectPaths.Difference(expectedPaths); len(extraPaths) > 0 {
 | 
				
			||||||
		t.Logf("Extra paths:\n%s", strings.Join(extraPaths.List(), "\n"))
 | 
							t.Logf("Extra paths:\n%s", strings.Join(sets.List[string](extraPaths), "\n"))
 | 
				
			||||||
		t.Error("Extra fields with resource in the name found. Verify VisitPodConfigmapNames() is including these fields if appropriate, then correct expectedPaths")
 | 
							t.Error("Extra fields with resource in the name found. Verify VisitPodConfigmapNames() is including these fields if appropriate, then correct expectedPaths")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if missingNames := expectedPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
						if missingNames := expectedPaths.Difference(extractedNames); len(missingNames) > 0 {
 | 
				
			||||||
		t.Logf("Missing expected names:\n%s", strings.Join(missingNames.List(), "\n"))
 | 
							t.Logf("Missing expected names:\n%s", strings.Join(sets.List[string](missingNames), "\n"))
 | 
				
			||||||
		t.Error("Missing expected names. Verify the pod stub above includes these references, then verify VisitPodConfigmapNames() is correctly finding the missing names")
 | 
							t.Error("Missing expected names. Verify the pod stub above includes these references, then verify VisitPodConfigmapNames() is correctly finding the missing names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extraNames := extractedNames.Difference(expectedPaths); len(extraNames) > 0 {
 | 
						if extraNames := extractedNames.Difference(expectedPaths); len(extraNames) > 0 {
 | 
				
			||||||
		t.Logf("Extra names:\n%s", strings.Join(extraNames.List(), "\n"))
 | 
							t.Logf("Extra names:\n%s", strings.Join(sets.List[string](extraNames), "\n"))
 | 
				
			||||||
		t.Error("Extra names extracted. Verify VisitPodConfigmapNames() is correctly extracting resource names")
 | 
							t.Error("Extra names extracted. Verify VisitPodConfigmapNames() is correctly extracting resource names")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user